summaryrefslogtreecommitdiffstats
path: root/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/acl-cat.json42
-rw-r--r--src/commands/acl-deluser.json33
-rw-r--r--src/commands/acl-dryrun.json47
-rw-r--r--src/commands/acl-genpass.json28
-rw-r--r--src/commands/acl-getuser.json91
-rw-r--r--src/commands/acl-help.json23
-rw-r--r--src/commands/acl-list.json25
-rw-r--r--src/commands/acl-load.json21
-rw-r--r--src/commands/acl-log.json90
-rw-r--r--src/commands/acl-save.json25
-rw-r--r--src/commands/acl-setuser.json47
-rw-r--r--src/commands/acl-users.json25
-rw-r--r--src/commands/acl-whoami.json21
-rw-r--r--src/commands/acl.json12
-rw-r--r--src/commands/append.json53
-rw-r--r--src/commands/asking.json19
-rw-r--r--src/commands/auth.json43
-rw-r--r--src/commands/bgrewriteaof.json19
-rw-r--r--src/commands/bgsave.json40
-rw-r--r--src/commands/bitcount.json87
-rw-r--r--src/commands/bitfield.json159
-rw-r--r--src/commands/bitfield_ro.json69
-rw-r--r--src/commands/bitop.json99
-rw-r--r--src/commands/bitpos.json106
-rw-r--r--src/commands/blmove.json117
-rw-r--r--src/commands/blmpop.json105
-rw-r--r--src/commands/blpop.json80
-rw-r--r--src/commands/brpop.json79
-rw-r--r--src/commands/brpoplpush.json96
-rw-r--r--src/commands/bzmpop.json117
-rw-r--r--src/commands/bzpopmax.json85
-rw-r--r--src/commands/bzpopmin.json85
-rw-r--r--src/commands/client-caching.json41
-rw-r--r--src/commands/client-getname.json32
-rw-r--r--src/commands/client-getredir.json37
-rw-r--r--src/commands/client-help.json26
-rw-r--r--src/commands/client-id.json24
-rw-r--r--src/commands/client-info.json27
-rw-r--r--src/commands/client-kill.json159
-rw-r--r--src/commands/client-list.json93
-rw-r--r--src/commands/client-no-evict.json42
-rw-r--r--src/commands/client-no-touch.json40
-rw-r--r--src/commands/client-pause.json54
-rw-r--r--src/commands/client-reply.json47
-rw-r--r--src/commands/client-setinfo.json45
-rw-r--r--src/commands/client-setname.json33
-rw-r--r--src/commands/client-tracking.json80
-rw-r--r--src/commands/client-trackinginfo.json80
-rw-r--r--src/commands/client-unblock.json56
-rw-r--r--src/commands/client-unpause.json24
-rw-r--r--src/commands/client.json12
-rw-r--r--src/commands/cluster-addslots.json26
-rw-r--r--src/commands/cluster-addslotsrange.json36
-rw-r--r--src/commands/cluster-bumpepoch.json33
-rw-r--r--src/commands/cluster-count-failure-reports.json29
-rw-r--r--src/commands/cluster-countkeysinslot.json25
-rw-r--r--src/commands/cluster-delslots.json26
-rw-r--r--src/commands/cluster-delslotsrange.json36
-rw-r--r--src/commands/cluster-failover.json38
-rw-r--r--src/commands/cluster-flushslots.json19
-rw-r--r--src/commands/cluster-forget.json25
-rw-r--r--src/commands/cluster-getkeysinslot.json35
-rw-r--r--src/commands/cluster-help.json22
-rw-r--r--src/commands/cluster-info.json21
-rw-r--r--src/commands/cluster-keyslot.json25
-rw-r--r--src/commands/cluster-links.json60
-rw-r--r--src/commands/cluster-meet.json41
-rw-r--r--src/commands/cluster-myid.json18
-rw-r--r--src/commands/cluster-myshardid.json22
-rw-r--r--src/commands/cluster-nodes.json21
-rw-r--r--src/commands/cluster-replicas.json32
-rw-r--r--src/commands/cluster-replicate.json25
-rw-r--r--src/commands/cluster-reset.json38
-rw-r--r--src/commands/cluster-saveconfig.json19
-rw-r--r--src/commands/cluster-set-config-epoch.json25
-rw-r--r--src/commands/cluster-setslot.json54
-rw-r--r--src/commands/cluster-shards.json90
-rw-r--r--src/commands/cluster-slaves.json37
-rw-r--r--src/commands/cluster-slots.json136
-rw-r--r--src/commands/cluster.json9
-rw-r--r--src/commands/command-count.json23
-rw-r--r--src/commands/command-docs.json211
-rw-r--r--src/commands/command-getkeys.json39
-rw-r--r--src/commands/command-getkeysandflags.json55
-rw-r--r--src/commands/command-help.json26
-rw-r--r--src/commands/command-info.json213
-rw-r--r--src/commands/command-list.json55
-rw-r--r--src/commands/command.json21
-rw-r--r--src/commands/config-get.json36
-rw-r--r--src/commands/config-help.json22
-rw-r--r--src/commands/config-resetstat.json24
-rw-r--r--src/commands/config-rewrite.json24
-rw-r--r--src/commands/config-set.json47
-rw-r--r--src/commands/config.json9
-rw-r--r--src/commands/copy.json91
-rw-r--r--src/commands/dbsize.json25
-rw-r--r--src/commands/debug.json20
-rw-r--r--src/commands/decr.json50
-rw-r--r--src/commands/decrby.json54
-rw-r--r--src/commands/del.json53
-rw-r--r--src/commands/discard.json23
-rw-r--r--src/commands/dump.json58
-rw-r--r--src/commands/echo.json28
-rw-r--r--src/commands/eval.json69
-rw-r--r--src/commands/eval_ro.json68
-rw-r--r--src/commands/evalsha.json68
-rw-r--r--src/commands/evalsha_ro.json67
-rw-r--r--src/commands/exec.json31
-rw-r--r--src/commands/exists.json58
-rw-r--r--src/commands/expire.json94
-rw-r--r--src/commands/expireat.json94
-rw-r--r--src/commands/expiretime.json61
-rw-r--r--src/commands/failover.json54
-rw-r--r--src/commands/fcall.json69
-rw-r--r--src/commands/fcall_ro.json68
-rw-r--r--src/commands/flushall.json55
-rw-r--r--src/commands/flushdb.json55
-rw-r--r--src/commands/function-delete.json31
-rw-r--r--src/commands/function-dump.json21
-rw-r--r--src/commands/function-flush.json44
-rw-r--r--src/commands/function-help.json25
-rw-r--r--src/commands/function-kill.json25
-rw-r--r--src/commands/function-list.json87
-rw-r--r--src/commands/function-load.json39
-rw-r--r--src/commands/function-restore.json54
-rw-r--r--src/commands/function-stats.json81
-rw-r--r--src/commands/function.json9
-rw-r--r--src/commands/geoadd.json98
-rw-r--r--src/commands/geodist.json91
-rw-r--r--src/commands/geohash.json56
-rw-r--r--src/commands/geopos.json76
-rw-r--r--src/commands/georadius.json270
-rw-r--r--src/commands/georadius_ro.json201
-rw-r--r--src/commands/georadiusbymember.json261
-rw-r--r--src/commands/georadiusbymember_ro.json190
-rw-r--r--src/commands/geosearch.json267
-rw-r--r--src/commands/geosearchstore.json228
-rw-r--r--src/commands/get.json56
-rw-r--r--src/commands/getbit.json59
-rw-r--r--src/commands/getdel.json57
-rw-r--r--src/commands/getex.json90
-rw-r--r--src/commands/getrange.json55
-rw-r--r--src/commands/getset.json67
-rw-r--r--src/commands/hdel.json59
-rw-r--r--src/commands/hello.json111
-rw-r--r--src/commands/hexists.json59
-rw-r--r--src/commands/hget.json60
-rw-r--r--src/commands/hgetall.json53
-rw-r--r--src/commands/hincrby.json58
-rw-r--r--src/commands/hincrbyfloat.json58
-rw-r--r--src/commands/hkeys.json54
-rw-r--r--src/commands/hlen.json47
-rw-r--r--src/commands/hmget.json64
-rw-r--r--src/commands/hmset.json68
-rw-r--r--src/commands/hrandfield.json101
-rw-r--r--src/commands/hscan.json81
-rw-r--r--src/commands/hset.json70
-rw-r--r--src/commands/hsetnx.json65
-rw-r--r--src/commands/hstrlen.json52
-rw-r--r--src/commands/hvals.json53
-rw-r--r--src/commands/incr.json50
-rw-r--r--src/commands/incrby.json54
-rw-r--r--src/commands/incrbyfloat.json54
-rw-r--r--src/commands/info.json41
-rw-r--r--src/commands/keys.json34
-rw-r--r--src/commands/lastsave.json26
-rw-r--r--src/commands/latency-doctor.json26
-rw-r--r--src/commands/latency-graph.json32
-rw-r--r--src/commands/latency-help.json22
-rw-r--r--src/commands/latency-histogram.json54
-rw-r--r--src/commands/latency-history.json49
-rw-r--r--src/commands/latency-latest.json49
-rw-r--r--src/commands/latency-reset.json33
-rw-r--r--src/commands/latency.json9
-rw-r--r--src/commands/lcs.json127
-rw-r--r--src/commands/lindex.json59
-rw-r--r--src/commands/linsert.json85
-rw-r--r--src/commands/llen.json48
-rw-r--r--src/commands/lmove.json104
-rw-r--r--src/commands/lmpop.json100
-rw-r--r--src/commands/lolwut.json25
-rw-r--r--src/commands/lpop.json77
-rw-r--r--src/commands/lpos.json85
-rw-r--r--src/commands/lpush.json60
-rw-r--r--src/commands/lpushx.json61
-rw-r--r--src/commands/lrange.json58
-rw-r--r--src/commands/lrem.json56
-rw-r--r--src/commands/lset.json55
-rw-r--r--src/commands/ltrim.json54
-rw-r--r--src/commands/memory-doctor.json20
-rw-r--r--src/commands/memory-help.json22
-rw-r--r--src/commands/memory-malloc-stats.json20
-rw-r--r--src/commands/memory-purge.json18
-rw-r--r--src/commands/memory-stats.json121
-rw-r--r--src/commands/memory-usage.json58
-rw-r--r--src/commands/memory.json9
-rw-r--r--src/commands/mget.json63
-rw-r--r--src/commands/migrate.json181
-rw-r--r--src/commands/module-help.json22
-rw-r--r--src/commands/module-list.json47
-rw-r--r--src/commands/module-load.json32
-rw-r--r--src/commands/module-loadex.json51
-rw-r--r--src/commands/module-unload.json26
-rw-r--r--src/commands/module.json9
-rw-r--r--src/commands/monitor.json16
-rw-r--r--src/commands/move.json61
-rw-r--r--src/commands/mset.json62
-rw-r--r--src/commands/msetnx.json67
-rw-r--r--src/commands/multi.json23
-rw-r--r--src/commands/object-encoding.json58
-rw-r--r--src/commands/object-freq.json50
-rw-r--r--src/commands/object-help.json25
-rw-r--r--src/commands/object-idletime.json50
-rw-r--r--src/commands/object-refcount.json50
-rw-r--r--src/commands/object.json9
-rw-r--r--src/commands/persist.json56
-rw-r--r--src/commands/pexpire.json94
-rw-r--r--src/commands/pexpireat.json94
-rw-r--r--src/commands/pexpiretime.json61
-rw-r--r--src/commands/pfadd.json63
-rw-r--r--src/commands/pfcount.json50
-rw-r--r--src/commands/pfdebug.json52
-rw-r--r--src/commands/pfmerge.json73
-rw-r--r--src/commands/pfselftest.json22
-rw-r--r--src/commands/ping.json40
-rw-r--r--src/commands/psetex.json60
-rw-r--r--src/commands/psubscribe.json24
-rw-r--r--src/commands/psync.json25
-rw-r--r--src/commands/pttl.json70
-rw-r--r--src/commands/publish.json33
-rw-r--r--src/commands/pubsub-channels.json31
-rw-r--r--src/commands/pubsub-help.json22
-rw-r--r--src/commands/pubsub-numpat.json21
-rw-r--r--src/commands/pubsub-numsub.json28
-rw-r--r--src/commands/pubsub-shardchannels.json31
-rw-r--r--src/commands/pubsub-shardnumsub.json28
-rw-r--r--src/commands/pubsub.json9
-rw-r--r--src/commands/punsubscribe.json25
-rw-r--r--src/commands/quit.json29
-rw-r--r--src/commands/randomkey.json34
-rw-r--r--src/commands/readonly.json21
-rw-r--r--src/commands/readwrite.json21
-rw-r--r--src/commands/rename.json72
-rw-r--r--src/commands/renamenx.json86
-rw-r--r--src/commands/replconf.json23
-rw-r--r--src/commands/replicaof.json59
-rw-r--r--src/commands/reset.json24
-rw-r--r--src/commands/restore-asking.json102
-rw-r--r--src/commands/restore.json98
-rw-r--r--src/commands/role.json134
-rw-r--r--src/commands/rpop.json76
-rw-r--r--src/commands/rpoplpush.json85
-rw-r--r--src/commands/rpush.json61
-rw-r--r--src/commands/rpushx.json61
-rw-r--r--src/commands/sadd.json60
-rw-r--r--src/commands/save.json19
-rw-r--r--src/commands/scan.json72
-rw-r--r--src/commands/scard.json48
-rw-r--r--src/commands/script-debug.json43
-rw-r--r--src/commands/script-exists.json44
-rw-r--r--src/commands/script-flush.json50
-rw-r--r--src/commands/script-help.json25
-rw-r--r--src/commands/script-kill.json25
-rw-r--r--src/commands/script-load.json32
-rw-r--r--src/commands/script.json9
-rw-r--r--src/commands/sdiff.json55
-rw-r--r--src/commands/sdiffstore.json73
-rw-r--r--src/commands/select.json27
-rw-r--r--src/commands/sentinel-ckquorum.json26
-rw-r--r--src/commands/sentinel-config.json121
-rw-r--r--src/commands/sentinel-debug.json49
-rw-r--r--src/commands/sentinel-failover.json25
-rw-r--r--src/commands/sentinel-flushconfig.json20
-rw-r--r--src/commands/sentinel-get-master-addr-by-name.json38
-rw-r--r--src/commands/sentinel-help.json24
-rw-r--r--src/commands/sentinel-info-cache.json64
-rw-r--r--src/commands/sentinel-is-master-down-by-addr.json61
-rw-r--r--src/commands/sentinel-master.json29
-rw-r--r--src/commands/sentinel-masters.json26
-rw-r--r--src/commands/sentinel-monitor.json37
-rw-r--r--src/commands/sentinel-myid.json20
-rw-r--r--src/commands/sentinel-pending-scripts.json52
-rw-r--r--src/commands/sentinel-remove.json25
-rw-r--r--src/commands/sentinel-replicas.json32
-rw-r--r--src/commands/sentinel-reset.json26
-rw-r--r--src/commands/sentinel-sentinels.json32
-rw-r--r--src/commands/sentinel-set.json40
-rw-r--r--src/commands/sentinel-simulate-failure.json52
-rw-r--r--src/commands/sentinel-slaves.json37
-rw-r--r--src/commands/sentinel.json14
-rw-r--r--src/commands/set.json152
-rw-r--r--src/commands/setbit.json64
-rw-r--r--src/commands/setex.json60
-rw-r--r--src/commands/setnx.json66
-rw-r--r--src/commands/setrange.json57
-rw-r--r--src/commands/shutdown.json69
-rw-r--r--src/commands/sinter.json55
-rw-r--r--src/commands/sintercard.json60
-rw-r--r--src/commands/sinterstore.json73
-rw-r--r--src/commands/sismember.json59
-rw-r--r--src/commands/slaveof.json64
-rw-r--r--src/commands/slowlog-get.json74
-rw-r--r--src/commands/slowlog-help.json22
-rw-r--r--src/commands/slowlog-len.json26
-rw-r--r--src/commands/slowlog-reset.json23
-rw-r--r--src/commands/slowlog.json9
-rw-r--r--src/commands/smembers.json54
-rw-r--r--src/commands/smismember.json66
-rw-r--r--src/commands/smove.json84
-rw-r--r--src/commands/sort.json162
-rw-r--r--src/commands/sort_ro.json132
-rw-r--r--src/commands/spop.json80
-rw-r--r--src/commands/spublish.json51
-rw-r--r--src/commands/srandmember.json83
-rw-r--r--src/commands/srem.json60
-rw-r--r--src/commands/sscan.json81
-rw-r--r--src/commands/ssubscribe.json42
-rw-r--r--src/commands/strlen.json48
-rw-r--r--src/commands/subscribe.json25
-rw-r--r--src/commands/substr.json60
-rw-r--r--src/commands/sunion.json55
-rw-r--r--src/commands/sunionstore.json73
-rw-r--r--src/commands/sunsubscribe.json43
-rw-r--r--src/commands/swapdb.json31
-rw-r--r--src/commands/sync.json15
-rw-r--r--src/commands/time.json28
-rw-r--r--src/commands/touch.json53
-rw-r--r--src/commands/ttl.json70
-rw-r--r--src/commands/type.json55
-rw-r--r--src/commands/unlink.json54
-rw-r--r--src/commands/unsubscribe.json25
-rw-r--r--src/commands/unwatch.json23
-rw-r--r--src/commands/wait.json34
-rw-r--r--src/commands/waitaof.json52
-rw-r--r--src/commands/watch.json50
-rw-r--r--src/commands/xack.json58
-rw-r--r--src/commands/xadd.json161
-rw-r--r--src/commands/xautoclaim.json158
-rw-r--r--src/commands/xclaim.json138
-rw-r--r--src/commands/xdel.json54
-rw-r--r--src/commands/xgroup-create.json85
-rw-r--r--src/commands/xgroup-createconsumer.json64
-rw-r--r--src/commands/xgroup-delconsumer.json57
-rw-r--r--src/commands/xgroup-destroy.json59
-rw-r--r--src/commands/xgroup-help.json25
-rw-r--r--src/commands/xgroup-setid.json79
-rw-r--r--src/commands/xgroup.json9
-rw-r--r--src/commands/xinfo-consumers.json80
-rw-r--r--src/commands/xinfo-groups.json92
-rw-r--r--src/commands/xinfo-help.json25
-rw-r--r--src/commands/xinfo-stream.json361
-rw-r--r--src/commands/xinfo.json9
-rw-r--r--src/commands/xlen.json48
-rw-r--r--src/commands/xpending.json160
-rw-r--r--src/commands/xrange.json87
-rw-r--r--src/commands/xread.json108
-rw-r--r--src/commands/xreadgroup.json134
-rw-r--r--src/commands/xrevrange.json86
-rw-r--r--src/commands/xsetid.json72
-rw-r--r--src/commands/xtrim.json108
-rw-r--r--src/commands/zadd.json144
-rw-r--r--src/commands/zcard.json47
-rw-r--r--src/commands/zcount.json56
-rw-r--r--src/commands/zdiff.json85
-rw-r--r--src/commands/zdiffstore.json77
-rw-r--r--src/commands/zincrby.json58
-rw-r--r--src/commands/zinter.json115
-rw-r--r--src/commands/zintercard.json60
-rw-r--r--src/commands/zinterstore.json108
-rw-r--r--src/commands/zlexcount.json57
-rw-r--r--src/commands/zmpop.json111
-rw-r--r--src/commands/zmscore.json65
-rw-r--r--src/commands/zpopmax.json89
-rw-r--r--src/commands/zpopmin.json89
-rw-r--r--src/commands/zrandmember.json101
-rw-r--r--src/commands/zrange.json137
-rw-r--r--src/commands/zrangebylex.json80
-rw-r--r--src/commands/zrangebyscore.json119
-rw-r--r--src/commands/zrangestore.json118
-rw-r--r--src/commands/zrank.json86
-rw-r--r--src/commands/zrem.json60
-rw-r--r--src/commands/zremrangebylex.json55
-rw-r--r--src/commands/zremrangebyrank.json55
-rw-r--r--src/commands/zremrangebyscore.json55
-rw-r--r--src/commands/zrevrange.json94
-rw-r--r--src/commands/zrevrangebylex.json80
-rw-r--r--src/commands/zrevrangebyscore.json118
-rw-r--r--src/commands/zrevrank.json86
-rw-r--r--src/commands/zscan.json81
-rw-r--r--src/commands/zscore.json60
-rw-r--r--src/commands/zunion.json115
-rw-r--r--src/commands/zunionstore.json107
392 files changed, 23626 insertions, 0 deletions
diff --git a/src/commands/acl-cat.json b/src/commands/acl-cat.json
new file mode 100644
index 0000000..dfbe4c4
--- /dev/null
+++ b/src/commands/acl-cat.json
@@ -0,0 +1,42 @@
+{
+ "CAT": {
+ "summary": "Lists the ACL categories, or the commands inside a category.",
+ "complexity": "O(1) since the categories and commands are a fixed set.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "array",
+ "description": "In case `category` was not given, a list of existing ACL categories",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "description": "In case `category` was given, list of commands that fall under the provided ACL category",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "category",
+ "type": "string",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-deluser.json b/src/commands/acl-deluser.json
new file mode 100644
index 0000000..80e8a7a
--- /dev/null
+++ b/src/commands/acl-deluser.json
@@ -0,0 +1,33 @@
+{
+ "DELUSER": {
+ "summary": "Deletes ACL users, and terminates their connections.",
+ "complexity": "O(1) amortized time considering the typical user.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -3,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of users that were deleted"
+ },
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-dryrun.json b/src/commands/acl-dryrun.json
new file mode 100644
index 0000000..bee6a6a
--- /dev/null
+++ b/src/commands/acl-dryrun.json
@@ -0,0 +1,47 @@
+{
+ "DRYRUN": {
+ "summary": "Simulates the execution of a command by a user, without executing the command.",
+ "complexity": "O(1).",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -4,
+ "container": "ACL",
+ "function": "aclCommand",
+ "history": [],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "const": "OK",
+ "description": "The given user may successfully execute the given command."
+ },
+ {
+ "type": "string",
+ "description": "The description of the problem, in case the user is not allowed to run the given command."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string"
+ },
+ {
+ "name": "command",
+ "type": "string"
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-genpass.json b/src/commands/acl-genpass.json
new file mode 100644
index 0000000..86c1f8e
--- /dev/null
+++ b/src/commands/acl-genpass.json
@@ -0,0 +1,28 @@
+{
+ "GENPASS": {
+ "summary": "Generates a pseudorandom, secure password that can be used to identify ACL users.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "Pseudorandom data. By default it contains 64 bytes, representing 256 bits of data. If `bits` was given, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4."
+ },
+ "arguments": [
+ {
+ "name": "bits",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-getuser.json b/src/commands/acl-getuser.json
new file mode 100644
index 0000000..535389b
--- /dev/null
+++ b/src/commands/acl-getuser.json
@@ -0,0 +1,91 @@
+{
+ "GETUSER": {
+ "summary": "Lists the ACL rules of a user.",
+ "complexity": "O(N). Where N is the number of password, command and pattern rules that the user has.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 3,
+ "container": "ACL",
+ "function": "aclCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added Pub/Sub channel patterns."
+ ],
+ [
+ "7.0.0",
+ "Added selectors and changed the format of key and channel patterns from a list to their rule representation."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "a set of ACL rule definitions for the user",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "flags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "passwords": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "commands": {
+ "description": "root selector's commands",
+ "type": "string"
+ },
+ "keys": {
+ "description": "root selector's keys",
+ "type": "string"
+ },
+ "channels": {
+ "description": "root selector's channels",
+ "type": "string"
+ },
+ "selectors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "commands": {
+ "type": "string"
+ },
+ "keys": {
+ "type": "string"
+ },
+ "channels": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "description": "If user does not exist",
+ "type": "null"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/acl-help.json b/src/commands/acl-help.json
new file mode 100644
index 0000000..3c95914
--- /dev/null
+++ b/src/commands/acl-help.json
@@ -0,0 +1,23 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "A list of subcommands and their description",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/acl-list.json b/src/commands/acl-list.json
new file mode 100644
index 0000000..0d75b13
--- /dev/null
+++ b/src/commands/acl-list.json
@@ -0,0 +1,25 @@
+{
+ "LIST": {
+ "summary": "Dumps the effective rules in ACL file format.",
+ "complexity": "O(N). Where N is the number of configured users.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "A list of currently active ACL rules",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/acl-load.json b/src/commands/acl-load.json
new file mode 100644
index 0000000..d7b91ba
--- /dev/null
+++ b/src/commands/acl-load.json
@@ -0,0 +1,21 @@
+{
+ "LOAD": {
+ "summary": "Reloads the rules from the configured ACL file.",
+ "complexity": "O(N). Where N is the number of configured users.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/acl-log.json b/src/commands/acl-log.json
new file mode 100644
index 0000000..de5f029
--- /dev/null
+++ b/src/commands/acl-log.json
@@ -0,0 +1,90 @@
+{
+ "LOG": {
+ "summary": "Lists recent security events generated due to ACL rules.",
+ "complexity": "O(N) with N being the number of entries shown.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "history": [
+ [
+ "7.2.0",
+ "Added entry ID, timestamp created, and timestamp last updated."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "In case `RESET` was not given, a list of recent ACL security events.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "context": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ },
+ "age-seconds": {
+ "type": "number"
+ },
+ "client-info": {
+ "type": "string"
+ },
+ "entry-id": {
+ "type": "integer"
+ },
+ "timestamp-created": {
+ "type": "integer"
+ },
+ "timestamp-last-updated": {
+ "type": "integer"
+ }
+ }
+ }
+ },
+ {
+ "const": "OK",
+ "description": "In case `RESET` was given, OK indicates ACL log was cleared."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "operation",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "reset",
+ "type": "pure-token",
+ "token": "RESET"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-save.json b/src/commands/acl-save.json
new file mode 100644
index 0000000..98d8dfd
--- /dev/null
+++ b/src/commands/acl-save.json
@@ -0,0 +1,25 @@
+{
+ "SAVE": {
+ "summary": "Saves the effective ACL rules in the configured ACL file.",
+ "complexity": "O(N). Where N is the number of configured users.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/acl-setuser.json b/src/commands/acl-setuser.json
new file mode 100644
index 0000000..1a90917
--- /dev/null
+++ b/src/commands/acl-setuser.json
@@ -0,0 +1,47 @@
+{
+ "SETUSER": {
+ "summary": "Creates and modifies an ACL user and its rules.",
+ "complexity": "O(N). Where N is the number of rules provided.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -3,
+ "container": "ACL",
+ "function": "aclCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added Pub/Sub channel patterns."
+ ],
+ [
+ "7.0.0",
+ "Added selectors and key based permissions."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string"
+ },
+ {
+ "name": "rule",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/acl-users.json b/src/commands/acl-users.json
new file mode 100644
index 0000000..1a6bc75
--- /dev/null
+++ b/src/commands/acl-users.json
@@ -0,0 +1,25 @@
+{
+ "USERS": {
+ "summary": "Lists all ACL users.",
+ "complexity": "O(N). Where N is the number of configured users.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of existing ACL users",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/acl-whoami.json b/src/commands/acl-whoami.json
new file mode 100644
index 0000000..2efe98c
--- /dev/null
+++ b/src/commands/acl-whoami.json
@@ -0,0 +1,21 @@
+{
+ "WHOAMI": {
+ "summary": "Returns the authenticated username of the current connection.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "ACL",
+ "function": "aclCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The username of the current connection."
+ }
+ }
+}
diff --git a/src/commands/acl.json b/src/commands/acl.json
new file mode 100644
index 0000000..1474b78
--- /dev/null
+++ b/src/commands/acl.json
@@ -0,0 +1,12 @@
+{
+ "ACL": {
+ "summary": "A container for Access List Control commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "6.0.0",
+ "arity": -2,
+ "command_flags": [
+ "SENTINEL"
+ ]
+ }
+}
diff --git a/src/commands/append.json b/src/commands/append.json
new file mode 100644
index 0000000..a8ec6bf
--- /dev/null
+++ b/src/commands/append.json
@@ -0,0 +1,53 @@
+{
+ "APPEND": {
+ "summary": "Appends a string to the value of a key. Creates the key if it doesn't exist.",
+ "complexity": "O(1). The amortized time complexity is O(1) assuming the appended value is small and the already present value is of any size, since the dynamic string library used by Redis will double the free space available on every reallocation.",
+ "group": "string",
+ "since": "2.0.0",
+ "arity": 3,
+ "function": "appendCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The length of the string after the append operation."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/asking.json b/src/commands/asking.json
new file mode 100644
index 0000000..3886795
--- /dev/null
+++ b/src/commands/asking.json
@@ -0,0 +1,19 @@
+{
+ "ASKING": {
+ "summary": "Signals that a cluster client is following an -ASK redirect.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 1,
+ "function": "askingCommand",
+ "command_flags": [
+ "FAST"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/auth.json b/src/commands/auth.json
new file mode 100644
index 0000000..3b1ba35
--- /dev/null
+++ b/src/commands/auth.json
@@ -0,0 +1,43 @@
+{
+ "AUTH": {
+ "summary": "Authenticates the connection.",
+ "complexity": "O(N) where N is the number of passwords defined for the user",
+ "group": "connection",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "authCommand",
+ "history": [
+ [
+ "6.0.0",
+ "Added ACL style (username and password)."
+ ]
+ ],
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "NO_AUTH",
+ "SENTINEL",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string",
+ "optional": true,
+ "since": "6.0.0"
+ },
+ {
+ "name": "password",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/bgrewriteaof.json b/src/commands/bgrewriteaof.json
new file mode 100644
index 0000000..6267d31
--- /dev/null
+++ b/src/commands/bgrewriteaof.json
@@ -0,0 +1,19 @@
+{
+ "BGREWRITEAOF": {
+ "summary": "Asynchronously rewrites the append-only file to disk.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "bgrewriteaofCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT"
+ ],
+ "reply_schema": {
+ "description": "A simple string reply indicating that the rewriting started or is about to start ASAP",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/bgsave.json b/src/commands/bgsave.json
new file mode 100644
index 0000000..f73d8a8
--- /dev/null
+++ b/src/commands/bgsave.json
@@ -0,0 +1,40 @@
+{
+ "BGSAVE": {
+ "summary": "Asynchronously saves the database(s) to disk.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "bgsaveCommand",
+ "history": [
+ [
+ "3.2.2",
+ "Added the `SCHEDULE` option."
+ ]
+ ],
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT"
+ ],
+ "arguments": [
+ {
+ "name": "schedule",
+ "token": "SCHEDULE",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.2.2"
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": "Background saving started"
+ },
+ {
+ "const": "Background saving scheduled"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/bitcount.json b/src/commands/bitcount.json
new file mode 100644
index 0000000..2d277a8
--- /dev/null
+++ b/src/commands/bitcount.json
@@ -0,0 +1,87 @@
+{
+ "BITCOUNT": {
+ "summary": "Counts the number of set bits (population counting) in a string.",
+ "complexity": "O(N)",
+ "group": "bitmap",
+ "since": "2.6.0",
+ "arity": -2,
+ "function": "bitcountCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `BYTE|BIT` option."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "range",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "end",
+ "type": "integer"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "byte",
+ "type": "pure-token",
+ "token": "BYTE"
+ },
+ {
+ "name": "bit",
+ "type": "pure-token",
+ "token": "BIT"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of bits set to 1.",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/bitfield.json b/src/commands/bitfield.json
new file mode 100644
index 0000000..843cea8
--- /dev/null
+++ b/src/commands/bitfield.json
@@ -0,0 +1,159 @@
+{
+ "BITFIELD": {
+ "summary": "Performs arbitrary bitfield integer operations on strings.",
+ "complexity": "O(1) for each subcommand specified",
+ "group": "bitmap",
+ "since": "3.2.0",
+ "arity": -2,
+ "function": "bitfieldCommand",
+ "get_keys_function": "bitfieldGetKeys",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "notes": "This command allows both access and modification of the key",
+ "flags": [
+ "RW",
+ "UPDATE",
+ "ACCESS",
+ "VARIABLE_FLAGS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "operation",
+ "type": "oneof",
+ "multiple": true,
+ "optional": true,
+ "arguments": [
+ {
+ "token": "GET",
+ "name": "get-block",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "encoding",
+ "type": "string"
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "write",
+ "type": "block",
+ "arguments": [
+ {
+ "token": "OVERFLOW",
+ "name": "overflow-block",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "wrap",
+ "type": "pure-token",
+ "token": "WRAP"
+ },
+ {
+ "name": "sat",
+ "type": "pure-token",
+ "token": "SAT"
+ },
+ {
+ "name": "fail",
+ "type": "pure-token",
+ "token": "FAIL"
+ }
+ ]
+ },
+ {
+ "name": "write-operation",
+ "type": "oneof",
+ "arguments": [
+ {
+ "token": "SET",
+ "name": "set-block",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "encoding",
+ "type": "string"
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "value",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "token": "INCRBY",
+ "name": "incrby-block",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "encoding",
+ "type": "string"
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "increment",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "description": "The result of the subcommand at the same position",
+ "type": "integer"
+ },
+ {
+ "description": "In case OVERFLOW FAIL was given and overflows or underflows detected",
+ "type": "null"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/bitfield_ro.json b/src/commands/bitfield_ro.json
new file mode 100644
index 0000000..0b5aa71
--- /dev/null
+++ b/src/commands/bitfield_ro.json
@@ -0,0 +1,69 @@
+{
+ "BITFIELD_RO": {
+ "summary": "Performs arbitrary read-only bitfield integer operations on strings.",
+ "complexity": "O(1) for each subcommand specified",
+ "group": "bitmap",
+ "since": "6.0.0",
+ "arity": -2,
+ "function": "bitfieldroCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "token": "GET",
+ "name": "get-block",
+ "type": "block",
+ "optional": true,
+ "multiple": true,
+ "multiple_token": true,
+ "arguments": [
+ {
+ "name": "encoding",
+ "type": "string"
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "description": "The result of the subcommand at the same position",
+ "type": "integer"
+ }
+ }
+ }
+}
diff --git a/src/commands/bitop.json b/src/commands/bitop.json
new file mode 100644
index 0000000..d9e1ff9
--- /dev/null
+++ b/src/commands/bitop.json
@@ -0,0 +1,99 @@
+{
+ "BITOP": {
+ "summary": "Performs bitwise operations on multiple strings, and stores the result.",
+ "complexity": "O(N)",
+ "group": "bitmap",
+ "since": "2.6.0",
+ "arity": -4,
+ "function": "bitopCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 3
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "operation",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "and",
+ "type": "pure-token",
+ "token": "AND"
+ },
+ {
+ "name": "or",
+ "type": "pure-token",
+ "token": "OR"
+ },
+ {
+ "name": "xor",
+ "type": "pure-token",
+ "token": "XOR"
+ },
+ {
+ "name": "not",
+ "type": "pure-token",
+ "token": "NOT"
+ }
+ ]
+ },
+ {
+ "name": "destkey",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the size of the string stored in the destination key, that is equal to the size of the longest input string",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/bitpos.json b/src/commands/bitpos.json
new file mode 100644
index 0000000..11b0851
--- /dev/null
+++ b/src/commands/bitpos.json
@@ -0,0 +1,106 @@
+{
+ "BITPOS": {
+ "summary": "Finds the first set (1) or clear (0) bit in a string.",
+ "complexity": "O(N)",
+ "group": "bitmap",
+ "since": "2.8.7",
+ "arity": -3,
+ "function": "bitposCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `BYTE|BIT` option."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "bit",
+ "type": "integer"
+ },
+ {
+ "name": "range",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "end-unit-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "end",
+ "type": "integer"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "byte",
+ "type": "pure-token",
+ "token": "BYTE"
+ },
+ {
+ "name": "bit",
+ "type": "pure-token",
+ "token": "BIT"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "the position of the first bit set to 1 or 0 according to the request",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "In case the `bit` argument is 1 and the string is empty or composed of just zero bytes",
+ "const": -1
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/blmove.json b/src/commands/blmove.json
new file mode 100644
index 0000000..b316c52
--- /dev/null
+++ b/src/commands/blmove.json
@@ -0,0 +1,117 @@
+{
+ "BLMOVE": {
+ "summary": "Pops an element from a list, pushes it to another list and returns it. Blocks until an element is available otherwise. Deletes the list if the last element was moved.",
+ "complexity": "O(1)",
+ "group": "list",
+ "since": "6.2.0",
+ "arity": 6,
+ "function": "blmoveCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The popped element.",
+ "type": "string"
+ },
+ {
+ "description": "Operation timed-out",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "wherefrom",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ },
+ {
+ "name": "whereto",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/blmpop.json b/src/commands/blmpop.json
new file mode 100644
index 0000000..48bfa3e
--- /dev/null
+++ b/src/commands/blmpop.json
@@ -0,0 +1,105 @@
+{
+ "BLMPOP": {
+ "summary": "Pops the first element from one of multiple lists. Blocks until an element is available otherwise. Deletes the list if the last element was popped.",
+ "complexity": "O(N+M) where N is the number of provided keys and M is the number of elements returned.",
+ "group": "list",
+ "since": "7.0.0",
+ "arity": -5,
+ "function": "blmpopCommand",
+ "get_keys_function": "blmpopGetKeys",
+ "command_flags": [
+ "WRITE",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Operation timed-out",
+ "type": "null"
+ },
+ {
+ "description": "The key from which elements were popped and the popped elements",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "List key from which elements were popped.",
+ "type": "string"
+ },
+ {
+ "description": "Array of popped elements.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "timeout",
+ "type": "double"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "where",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/blpop.json b/src/commands/blpop.json
new file mode 100644
index 0000000..cf90f0a
--- /dev/null
+++ b/src/commands/blpop.json
@@ -0,0 +1,80 @@
+{
+ "BLPOP": {
+ "summary": "Removes and returns the first element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.",
+ "complexity": "O(N) where N is the number of provided keys.",
+ "group": "list",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "blpopCommand",
+ "history": [
+ [
+ "6.0.0",
+ "`timeout` is interpreted as a double instead of an integer."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -2,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "No element could be popped and timeout expired"
+ },
+ {
+ "description": "The key from which the element was popped and the value of the popped element",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "List key from which the element was popped.",
+ "type": "string"
+ },
+ {
+ "description": "Value of the popped element.",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/brpop.json b/src/commands/brpop.json
new file mode 100644
index 0000000..129f74d
--- /dev/null
+++ b/src/commands/brpop.json
@@ -0,0 +1,79 @@
+{
+ "BRPOP": {
+ "summary": "Removes and returns the last element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.",
+ "complexity": "O(N) where N is the number of provided keys.",
+ "group": "list",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "brpopCommand",
+ "history": [
+ [
+ "6.0.0",
+ "`timeout` is interpreted as a double instead of an integer."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -2,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "No element could be popped and the timeout expired.",
+ "type": "null"
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "The name of the key where an element was popped ",
+ "type": "string"
+ },
+ {
+ "description": "The value of the popped element",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/brpoplpush.json b/src/commands/brpoplpush.json
new file mode 100644
index 0000000..dce1516
--- /dev/null
+++ b/src/commands/brpoplpush.json
@@ -0,0 +1,96 @@
+{
+ "BRPOPLPUSH": {
+ "summary": "Pops an element from a list, pushes it to another list and returns it. Block until an element is available otherwise. Deletes the list if the last element was popped.",
+ "complexity": "O(1)",
+ "group": "list",
+ "since": "2.2.0",
+ "arity": 4,
+ "function": "brpoplpushCommand",
+ "history": [
+ [
+ "6.0.0",
+ "`timeout` is interpreted as a double instead of an integer."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`BLMOVE` with the `RIGHT` and `LEFT` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The element being popped from source and pushed to destination."
+ },
+ {
+ "type": "null",
+ "description": "Timeout is reached."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/bzmpop.json b/src/commands/bzmpop.json
new file mode 100644
index 0000000..4ff5c11
--- /dev/null
+++ b/src/commands/bzmpop.json
@@ -0,0 +1,117 @@
+{
+ "BZMPOP": {
+ "summary": "Removes and returns a member by score from one or more sorted sets. Blocks until a member is available otherwise. Deletes the sorted set if the last element was popped.",
+ "complexity": "O(K) + O(M*log(N)) where K is the number of provided keys, N being the number of elements in the sorted set, and M being the number of elements popped.",
+ "group": "sorted_set",
+ "since": "7.0.0",
+ "arity": -5,
+ "function": "bzmpopCommand",
+ "get_keys_function": "blmpopGetKeys",
+ "command_flags": [
+ "WRITE",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Timeout reached and no elements were popped.",
+ "type": "null"
+ },
+ {
+ "description": "The keyname and the popped members.",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Keyname",
+ "type": "string"
+ },
+ {
+ "description": "Popped members and their scores.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "timeout",
+ "type": "double"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "where",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/bzpopmax.json b/src/commands/bzpopmax.json
new file mode 100644
index 0000000..70b0b70
--- /dev/null
+++ b/src/commands/bzpopmax.json
@@ -0,0 +1,85 @@
+{
+ "BZPOPMAX": {
+ "summary": "Removes and returns the member with the highest score from one or more sorted sets. Blocks until a member available otherwise. Deletes the sorted set if the last element was popped.",
+ "complexity": "O(log(N)) with N being the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "5.0.0",
+ "arity": -3,
+ "function": "bzpopmaxCommand",
+ "history": [
+ [
+ "6.0.0",
+ "`timeout` is interpreted as a double instead of an integer."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -2,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Timeout reached and no elements were popped.",
+ "type": "null"
+ },
+ {
+ "description": "The keyname, popped member, and its score.",
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "Keyname",
+ "type": "string"
+ },
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/bzpopmin.json b/src/commands/bzpopmin.json
new file mode 100644
index 0000000..a2f305c
--- /dev/null
+++ b/src/commands/bzpopmin.json
@@ -0,0 +1,85 @@
+{
+ "BZPOPMIN": {
+ "summary": "Removes and returns the member with the lowest score from one or more sorted sets. Blocks until a member is available otherwise. Deletes the sorted set if the last element was popped.",
+ "complexity": "O(log(N)) with N being the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "5.0.0",
+ "arity": -3,
+ "function": "bzpopminCommand",
+ "history": [
+ [
+ "6.0.0",
+ "`timeout` is interpreted as a double instead of an integer."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -2,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Timeout reached and no elements were popped.",
+ "type": "null"
+ },
+ {
+ "description": "The keyname, popped member, and its score.",
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "Keyname",
+ "type": "string"
+ },
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "timeout",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-caching.json b/src/commands/client-caching.json
new file mode 100644
index 0000000..2a4ae89
--- /dev/null
+++ b/src/commands/client-caching.json
@@ -0,0 +1,41 @@
+{
+ "CACHING": {
+ "summary": "Instructs the server whether to track the keys in the next request.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.0.0",
+ "arity": 3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "mode",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "yes",
+ "type": "pure-token",
+ "token": "YES"
+ },
+ {
+ "name": "no",
+ "type": "pure-token",
+ "token": "NO"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-getname.json b/src/commands/client-getname.json
new file mode 100644
index 0000000..9e237af
--- /dev/null
+++ b/src/commands/client-getname.json
@@ -0,0 +1,32 @@
+{
+ "GETNAME": {
+ "summary": "Returns the name of the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "2.6.9",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The connection name of the current connection"
+ },
+ {
+ "type": "null",
+ "description": "Connection name was not set"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/client-getredir.json b/src/commands/client-getredir.json
new file mode 100644
index 0000000..6fdb002
--- /dev/null
+++ b/src/commands/client-getredir.json
@@ -0,0 +1,37 @@
+{
+ "GETREDIR": {
+ "summary": "Returns the client ID to which the connection's tracking notifications are redirected.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.0.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "Not redirecting notifications to any client."
+ },
+ {
+ "const": -1,
+ "description": "Client tracking is not enabled."
+ },
+ {
+ "type": "integer",
+ "description": "ID of the client we are redirecting the notifications to.",
+ "minimum": 1
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/client-help.json b/src/commands/client-help.json
new file mode 100644
index 0000000..b49294c
--- /dev/null
+++ b/src/commands/client-help.json
@@ -0,0 +1,26 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/client-id.json b/src/commands/client-id.json
new file mode 100644
index 0000000..7c2bf08
--- /dev/null
+++ b/src/commands/client-id.json
@@ -0,0 +1,24 @@
+{
+ "ID": {
+ "summary": "Returns the unique client ID of the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The id of the client"
+ }
+ }
+}
diff --git a/src/commands/client-info.json b/src/commands/client-info.json
new file mode 100644
index 0000000..93fa008
--- /dev/null
+++ b/src/commands/client-info.json
@@ -0,0 +1,27 @@
+{
+ "INFO": {
+ "summary": "Returns information about the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "a unique string, as described at the CLIENT LIST page, for the current client",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/client-kill.json b/src/commands/client-kill.json
new file mode 100644
index 0000000..bd0262d
--- /dev/null
+++ b/src/commands/client-kill.json
@@ -0,0 +1,159 @@
+{
+ "KILL": {
+ "summary": "Terminates open connections.",
+ "complexity": "O(N) where N is the number of client connections",
+ "group": "connection",
+ "since": "2.4.0",
+ "arity": -3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "history": [
+ [
+ "2.8.12",
+ "Added new filter format."
+ ],
+ [
+ "2.8.12",
+ "`ID` option."
+ ],
+ [
+ "3.2.0",
+ "Added `master` type in for `TYPE` option."
+ ],
+ [
+ "5.0.0",
+ "Replaced `slave` `TYPE` with `replica`. `slave` still supported for backward compatibility."
+ ],
+ [
+ "6.2.0",
+ "`LADDR` option."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "arguments": [
+ {
+ "name": "filter",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "old-format",
+ "display": "ip:port",
+ "type": "string",
+ "deprecated_since": "2.8.12"
+ },
+ {
+ "name": "new-format",
+ "type": "oneof",
+ "multiple": true,
+ "arguments": [
+ {
+ "token": "ID",
+ "name": "client-id",
+ "type": "integer",
+ "optional": true,
+ "since": "2.8.12"
+ },
+ {
+ "token": "TYPE",
+ "name": "client-type",
+ "type": "oneof",
+ "optional": true,
+ "since": "2.8.12",
+ "arguments": [
+ {
+ "name": "normal",
+ "type": "pure-token",
+ "token": "normal"
+ },
+ {
+ "name": "master",
+ "type": "pure-token",
+ "token": "master",
+ "since": "3.2.0"
+ },
+ {
+ "name": "slave",
+ "type": "pure-token",
+ "token": "slave"
+ },
+ {
+ "name": "replica",
+ "type": "pure-token",
+ "token": "replica",
+ "since": "5.0.0"
+ },
+ {
+ "name": "pubsub",
+ "type": "pure-token",
+ "token": "pubsub"
+ }
+ ]
+ },
+ {
+ "token": "USER",
+ "name": "username",
+ "type": "string",
+ "optional": true
+ },
+ {
+ "token": "ADDR",
+ "name": "addr",
+ "display": "ip:port",
+ "type": "string",
+ "optional": true
+ },
+ {
+ "token": "LADDR",
+ "name": "laddr",
+ "display": "ip:port",
+ "type": "string",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "token": "SKIPME",
+ "name": "skipme",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "yes",
+ "type": "pure-token",
+ "token": "YES"
+ },
+ {
+ "name": "no",
+ "type": "pure-token",
+ "token": "NO"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "when called in 3 argument format",
+ "const": "OK"
+ },
+ {
+ "description": "when called in filter/value format, the number of clients killed",
+ "type": "integer",
+ "minimum": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/client-list.json b/src/commands/client-list.json
new file mode 100644
index 0000000..f72ffaf
--- /dev/null
+++ b/src/commands/client-list.json
@@ -0,0 +1,93 @@
+{
+ "LIST": {
+ "summary": "Lists open connections.",
+ "complexity": "O(N) where N is the number of client connections",
+ "group": "connection",
+ "since": "2.4.0",
+ "arity": -2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "history": [
+ [
+ "2.8.12",
+ "Added unique client `id` field."
+ ],
+ [
+ "5.0.0",
+ "Added optional `TYPE` filter."
+ ],
+ [
+ "6.0.0",
+ "Added `user` field."
+ ],
+ [
+ "6.2.0",
+ "Added `argv-mem`, `tot-mem`, `laddr` and `redir` fields and the optional `ID` filter."
+ ],
+ [
+ "7.0.0",
+ "Added `resp`, `multi-mem`, `rbs` and `rbp` fields."
+ ],
+ [
+ "7.0.3",
+ "Added `ssub` field."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "Information and statistics about client connections"
+ },
+ "arguments": [
+ {
+ "token": "TYPE",
+ "name": "client-type",
+ "type": "oneof",
+ "optional": true,
+ "since": "5.0.0",
+ "arguments": [
+ {
+ "name": "normal",
+ "type": "pure-token",
+ "token": "normal"
+ },
+ {
+ "name": "master",
+ "type": "pure-token",
+ "token": "master"
+ },
+ {
+ "name": "replica",
+ "type": "pure-token",
+ "token": "replica"
+ },
+ {
+ "name": "pubsub",
+ "type": "pure-token",
+ "token": "pubsub"
+ }
+ ]
+ },
+ {
+ "name": "client-id",
+ "token": "ID",
+ "type": "integer",
+ "optional": true,
+ "multiple": true,
+ "since": "6.2.0"
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-no-evict.json b/src/commands/client-no-evict.json
new file mode 100644
index 0000000..9ed6718
--- /dev/null
+++ b/src/commands/client-no-evict.json
@@ -0,0 +1,42 @@
+{
+ "NO-EVICT": {
+ "summary": "Sets the client eviction mode of the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "7.0.0",
+ "arity": 3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "arguments": [
+ {
+ "name": "enabled",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "on",
+ "type": "pure-token",
+ "token": "ON"
+ },
+ {
+ "name": "off",
+ "type": "pure-token",
+ "token": "OFF"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/client-no-touch.json b/src/commands/client-no-touch.json
new file mode 100644
index 0000000..4cf7b72
--- /dev/null
+++ b/src/commands/client-no-touch.json
@@ -0,0 +1,40 @@
+{
+ "NO-TOUCH": {
+ "summary": "Controls whether commands sent by the client affect the LRU/LFU of accessed keys.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "7.2.0",
+ "arity": 3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "enabled",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "on",
+ "type": "pure-token",
+ "token": "ON"
+ },
+ {
+ "name": "off",
+ "type": "pure-token",
+ "token": "OFF"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-pause.json b/src/commands/client-pause.json
new file mode 100644
index 0000000..b1dd7bc
--- /dev/null
+++ b/src/commands/client-pause.json
@@ -0,0 +1,54 @@
+{
+ "PAUSE": {
+ "summary": "Suspends commands processing.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "3.0.0",
+ "arity": -3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "history": [
+ [
+ "6.2.0",
+ "`CLIENT PAUSE WRITE` mode added along with the `mode` option."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "arguments": [
+ {
+ "name": "timeout",
+ "type": "integer"
+ },
+ {
+ "name": "mode",
+ "type": "oneof",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "write",
+ "type": "pure-token",
+ "token": "WRITE"
+ },
+ {
+ "name": "all",
+ "type": "pure-token",
+ "token": "ALL"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/client-reply.json b/src/commands/client-reply.json
new file mode 100644
index 0000000..9406de8
--- /dev/null
+++ b/src/commands/client-reply.json
@@ -0,0 +1,47 @@
+{
+ "REPLY": {
+ "summary": "Instructs the server whether to reply to commands.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "3.2.0",
+ "arity": 3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK",
+ "description": "When called with either OFF or SKIP subcommands, no reply is made. When called with ON, reply is OK."
+ },
+ "arguments": [
+ {
+ "name": "action",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "on",
+ "type": "pure-token",
+ "token": "ON"
+ },
+ {
+ "name": "off",
+ "type": "pure-token",
+ "token": "OFF"
+ },
+ {
+ "name": "skip",
+ "type": "pure-token",
+ "token": "SKIP"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-setinfo.json b/src/commands/client-setinfo.json
new file mode 100644
index 0000000..d0d8f73
--- /dev/null
+++ b/src/commands/client-setinfo.json
@@ -0,0 +1,45 @@
+{
+ "SETINFO": {
+ "summary": "Sets information specific to the client or connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "7.2.0",
+ "arity": 4,
+ "container": "CLIENT",
+ "function": "clientSetinfoCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "attr",
+ "type": "oneof",
+ "arguments": [
+ {
+ "token": "lib-name",
+ "name": "libname",
+ "type": "string"
+ },
+ {
+ "token": "lib-ver",
+ "name": "libver",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-setname.json b/src/commands/client-setname.json
new file mode 100644
index 0000000..b071bd1
--- /dev/null
+++ b/src/commands/client-setname.json
@@ -0,0 +1,33 @@
+{
+ "SETNAME": {
+ "summary": "Sets the connection name.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "2.6.9",
+ "arity": 3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "arguments": [
+ {
+ "name": "connection-name",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/client-tracking.json b/src/commands/client-tracking.json
new file mode 100644
index 0000000..28e84ec
--- /dev/null
+++ b/src/commands/client-tracking.json
@@ -0,0 +1,80 @@
+{
+ "TRACKING": {
+ "summary": "Controls server-assisted client-side caching for the connection.",
+ "complexity": "O(1). Some options may introduce additional complexity.",
+ "group": "connection",
+ "since": "6.0.0",
+ "arity": -3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "arguments": [
+ {
+ "name": "status",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "on",
+ "type": "pure-token",
+ "token": "ON"
+ },
+ {
+ "name": "off",
+ "type": "pure-token",
+ "token": "OFF"
+ }
+ ]
+ },
+ {
+ "token": "REDIRECT",
+ "name": "client-id",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "PREFIX",
+ "name": "prefix",
+ "type": "string",
+ "optional": true,
+ "multiple": true,
+ "multiple_token": true
+ },
+ {
+ "name": "BCAST",
+ "token": "BCAST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "OPTIN",
+ "token": "OPTIN",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "OPTOUT",
+ "token": "OPTOUT",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "NOLOOP",
+ "token": "NOLOOP",
+ "type": "pure-token",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "if the client was successfully put into or taken out of tracking mode",
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/client-trackinginfo.json b/src/commands/client-trackinginfo.json
new file mode 100644
index 0000000..270a3d5
--- /dev/null
+++ b/src/commands/client-trackinginfo.json
@@ -0,0 +1,80 @@
+{
+ "TRACKINGINFO": {
+ "summary": "Returns information about server-assisted client-side caching for the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "flags": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "const": "off",
+ "description": "The connection isn't using server assisted client side caching."
+ },
+ {
+ "const": "on",
+ "description": "Server assisted client side caching is enabled for the connection."
+ },
+ {
+ "const": "bcast",
+ "description": "The client uses broadcasting mode."
+ },
+ {
+ "const": "optin",
+ "description": "The client does not cache keys by default."
+ },
+ {
+ "const": "optout",
+ "description": "The client caches keys by default."
+ },
+ {
+ "const": "caching-yes",
+ "description": "The next command will cache keys (exists only together with optin)."
+ },
+ {
+ "const": "caching-no",
+ "description": "The next command won't cache keys (exists only together with optout)."
+ },
+ {
+ "const": "noloop",
+ "description": "The client isn't notified about keys modified by itself."
+ },
+ {
+ "const": "broken_redirect",
+ "description": "The client ID used for redirection isn't valid anymore."
+ }
+ ]
+ }
+ },
+ "redirect": {
+ "type": "integer",
+ "description": "The client ID used for notifications redirection, or -1 when none."
+ },
+ "prefixes": {
+ "type": "array",
+ "description": "List of key prefixes for which notifications are sent to the client.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/client-unblock.json b/src/commands/client-unblock.json
new file mode 100644
index 0000000..d028f47
--- /dev/null
+++ b/src/commands/client-unblock.json
@@ -0,0 +1,56 @@
+{
+ "UNBLOCK": {
+ "summary": "Unblocks a client blocked by a blocking command from a different connection.",
+ "complexity": "O(log N) where N is the number of client connections",
+ "group": "connection",
+ "since": "5.0.0",
+ "arity": -3,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "if the client was unblocked successfully"
+ },
+ {
+ "const": 1,
+ "description": "if the client wasn't unblocked"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "client-id",
+ "type": "integer"
+ },
+ {
+ "name": "unblock-type",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "timeout",
+ "type": "pure-token",
+ "token": "TIMEOUT"
+ },
+ {
+ "name": "error",
+ "type": "pure-token",
+ "token": "ERROR"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/client-unpause.json b/src/commands/client-unpause.json
new file mode 100644
index 0000000..6c55210
--- /dev/null
+++ b/src/commands/client-unpause.json
@@ -0,0 +1,24 @@
+{
+ "UNPAUSE": {
+ "summary": "Resumes processing commands from paused clients.",
+ "complexity": "O(N) Where N is the number of paused clients",
+ "group": "connection",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "CLIENT",
+ "function": "clientCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/client.json b/src/commands/client.json
new file mode 100644
index 0000000..b509961
--- /dev/null
+++ b/src/commands/client.json
@@ -0,0 +1,12 @@
+{
+ "CLIENT": {
+ "summary": "A container for client connection commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "connection",
+ "since": "2.4.0",
+ "arity": -2,
+ "command_flags": [
+ "SENTINEL"
+ ]
+ }
+}
diff --git a/src/commands/cluster-addslots.json b/src/commands/cluster-addslots.json
new file mode 100644
index 0000000..4d2ea25
--- /dev/null
+++ b/src/commands/cluster-addslots.json
@@ -0,0 +1,26 @@
+{
+ "ADDSLOTS": {
+ "summary": "Assigns new hash slots to a node.",
+ "complexity": "O(N) where N is the total number of hash slot arguments",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "slot",
+ "type": "integer",
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-addslotsrange.json b/src/commands/cluster-addslotsrange.json
new file mode 100644
index 0000000..4ff8a40
--- /dev/null
+++ b/src/commands/cluster-addslotsrange.json
@@ -0,0 +1,36 @@
+{
+ "ADDSLOTSRANGE": {
+ "summary": "Assigns new hash slot ranges to a node.",
+ "complexity": "O(N) where N is the total number of the slots between the start slot and end slot arguments.",
+ "group": "cluster",
+ "since": "7.0.0",
+ "arity": -4,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "range",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "start-slot",
+ "type": "integer"
+ },
+ {
+ "name": "end-slot",
+ "type": "integer"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-bumpepoch.json b/src/commands/cluster-bumpepoch.json
new file mode 100644
index 0000000..786723c
--- /dev/null
+++ b/src/commands/cluster-bumpepoch.json
@@ -0,0 +1,33 @@
+{
+ "BUMPEPOCH": {
+ "summary": "Advances the cluster config epoch.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "if the epoch was incremented",
+ "type": "string",
+ "pattern": "^BUMPED [0-9]*$"
+ },
+ {
+ "description": "if the node already has the greatest config epoch in the cluster",
+ "type": "string",
+ "pattern": "^STILL [0-9]*$"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/cluster-count-failure-reports.json b/src/commands/cluster-count-failure-reports.json
new file mode 100644
index 0000000..b80632d
--- /dev/null
+++ b/src/commands/cluster-count-failure-reports.json
@@ -0,0 +1,29 @@
+{
+ "COUNT-FAILURE-REPORTS": {
+ "summary": "Returns the number of active failure reports active for a node.",
+ "complexity": "O(N) where N is the number of failure reports",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "ADMIN",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "arguments": [
+ {
+ "name": "node-id",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of active failure reports for the node",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/cluster-countkeysinslot.json b/src/commands/cluster-countkeysinslot.json
new file mode 100644
index 0000000..caeec51
--- /dev/null
+++ b/src/commands/cluster-countkeysinslot.json
@@ -0,0 +1,25 @@
+{
+ "COUNTKEYSINSLOT": {
+ "summary": "Returns the number of keys in a hash slot.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "slot",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of keys in the specified hash slot",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/cluster-delslots.json b/src/commands/cluster-delslots.json
new file mode 100644
index 0000000..0732d2b
--- /dev/null
+++ b/src/commands/cluster-delslots.json
@@ -0,0 +1,26 @@
+{
+ "DELSLOTS": {
+ "summary": "Sets hash slots as unbound for a node.",
+ "complexity": "O(N) where N is the total number of hash slot arguments",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "slot",
+ "type": "integer",
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-delslotsrange.json b/src/commands/cluster-delslotsrange.json
new file mode 100644
index 0000000..77f1aea
--- /dev/null
+++ b/src/commands/cluster-delslotsrange.json
@@ -0,0 +1,36 @@
+{
+ "DELSLOTSRANGE": {
+ "summary": "Sets hash slot ranges as unbound for a node.",
+ "complexity": "O(N) where N is the total number of the slots between the start slot and end slot arguments.",
+ "group": "cluster",
+ "since": "7.0.0",
+ "arity": -4,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "range",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "start-slot",
+ "type": "integer"
+ },
+ {
+ "name": "end-slot",
+ "type": "integer"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-failover.json b/src/commands/cluster-failover.json
new file mode 100644
index 0000000..f58fd56
--- /dev/null
+++ b/src/commands/cluster-failover.json
@@ -0,0 +1,38 @@
+{
+ "FAILOVER": {
+ "summary": "Forces a replica to perform a manual failover of its master.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "options",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "force",
+ "type": "pure-token",
+ "token": "FORCE"
+ },
+ {
+ "name": "takeover",
+ "type": "pure-token",
+ "token": "TAKEOVER"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-flushslots.json b/src/commands/cluster-flushslots.json
new file mode 100644
index 0000000..09902ad
--- /dev/null
+++ b/src/commands/cluster-flushslots.json
@@ -0,0 +1,19 @@
+{
+ "FLUSHSLOTS": {
+ "summary": "Deletes all slots information from a node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-forget.json b/src/commands/cluster-forget.json
new file mode 100644
index 0000000..6f9a25c
--- /dev/null
+++ b/src/commands/cluster-forget.json
@@ -0,0 +1,25 @@
+{
+ "FORGET": {
+ "summary": "Removes a node from the nodes table.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "node-id",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-getkeysinslot.json b/src/commands/cluster-getkeysinslot.json
new file mode 100644
index 0000000..039dfea
--- /dev/null
+++ b/src/commands/cluster-getkeysinslot.json
@@ -0,0 +1,35 @@
+{
+ "GETKEYSINSLOT": {
+ "summary": "Returns the key names in a hash slot.",
+ "complexity": "O(N) where N is the number of requested keys",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 4,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "arguments": [
+ {
+ "name": "slot",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "description": "an array with up to count elements",
+ "type": "array",
+ "items": {
+ "description": "key name",
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-help.json b/src/commands/cluster-help.json
new file mode 100644
index 0000000..27f7d08
--- /dev/null
+++ b/src/commands/cluster-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-info.json b/src/commands/cluster-info.json
new file mode 100644
index 0000000..2c88760
--- /dev/null
+++ b/src/commands/cluster-info.json
@@ -0,0 +1,21 @@
+{
+ "INFO": {
+ "summary": "Returns information about the state of a node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "A map between named fields and values in the form of <field>:<value> lines separated by newlines composed by the two bytes CRLF",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/cluster-keyslot.json b/src/commands/cluster-keyslot.json
new file mode 100644
index 0000000..e51b643
--- /dev/null
+++ b/src/commands/cluster-keyslot.json
@@ -0,0 +1,25 @@
+{
+ "KEYSLOT": {
+ "summary": "Returns the hash slot for a key.",
+ "complexity": "O(N) where N is the number of bytes in the key",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The hash slot number for the specified key",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/cluster-links.json b/src/commands/cluster-links.json
new file mode 100644
index 0000000..07b2e83
--- /dev/null
+++ b/src/commands/cluster-links.json
@@ -0,0 +1,60 @@
+{
+ "LINKS": {
+ "summary": "Returns a list of all TCP links to and from peer nodes.",
+ "complexity": "O(N) where N is the total number of Cluster nodes",
+ "group": "cluster",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "an array of cluster links and their attributes",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "direction": {
+ "description": "This link is established by the local node _to_ the peer, or accepted by the local node _from_ the peer.",
+ "oneOf": [
+ {
+ "description": "connection initiated from peer",
+ "const": "from"
+ },
+ {
+ "description": "connection initiated to peer",
+ "const": "to"
+ }
+ ]
+ },
+ "node": {
+ "description": "the node id of the peer",
+ "type": "string"
+ },
+ "create-time": {
+ "description": "unix time creation time of the link. (In the case of a _to_ link, this is the time when the TCP link is created by the local node, not the time when it is actually established.)",
+ "type": "integer"
+ },
+ "events": {
+ "description": "events currently registered for the link. r means readable event, w means writable event",
+ "type": "string"
+ },
+ "send-buffer-allocated": {
+ "description": "allocated size of the link's send buffer, which is used to buffer outgoing messages toward the peer",
+ "type": "integer"
+ },
+ "send-buffer-used": {
+ "description": "size of the portion of the link's send buffer that is currently holding data(messages)",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-meet.json b/src/commands/cluster-meet.json
new file mode 100644
index 0000000..7ca23a7
--- /dev/null
+++ b/src/commands/cluster-meet.json
@@ -0,0 +1,41 @@
+{
+ "MEET": {
+ "summary": "Forces a node to handshake with another node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -4,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Added the optional `cluster_bus_port` argument."
+ ]
+ ],
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "ip",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ },
+ {
+ "name": "cluster-bus-port",
+ "type": "integer",
+ "optional": true,
+ "since": "4.0.0"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-myid.json b/src/commands/cluster-myid.json
new file mode 100644
index 0000000..340d425
--- /dev/null
+++ b/src/commands/cluster-myid.json
@@ -0,0 +1,18 @@
+{
+ "MYID": {
+ "summary": "Returns the ID of a node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "reply_schema": {
+ "description": "the node id",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/cluster-myshardid.json b/src/commands/cluster-myshardid.json
new file mode 100644
index 0000000..7db63fd
--- /dev/null
+++ b/src/commands/cluster-myshardid.json
@@ -0,0 +1,22 @@
+{
+ "MYSHARDID": {
+ "summary": "Returns the shard ID of a node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "7.2.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "history": [],
+ "command_flags": [
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "the node's shard id",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/cluster-nodes.json b/src/commands/cluster-nodes.json
new file mode 100644
index 0000000..ce34944
--- /dev/null
+++ b/src/commands/cluster-nodes.json
@@ -0,0 +1,21 @@
+{
+ "NODES": {
+ "summary": "Returns the cluster configuration for a node.",
+ "complexity": "O(N) where N is the total number of Cluster nodes",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "the serialized cluster configuration",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/cluster-replicas.json b/src/commands/cluster-replicas.json
new file mode 100644
index 0000000..e01617f
--- /dev/null
+++ b/src/commands/cluster-replicas.json
@@ -0,0 +1,32 @@
+{
+ "REPLICAS": {
+ "summary": "Lists the replica nodes of a master node.",
+ "complexity": "O(N) where N is the number of replicas.",
+ "group": "cluster",
+ "since": "5.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "ADMIN",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "arguments": [
+ {
+ "name": "node-id",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "a list of replica nodes replicating from the specified master node provided in the same format used by CLUSTER NODES",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "description": "the serialized cluster configuration"
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-replicate.json b/src/commands/cluster-replicate.json
new file mode 100644
index 0000000..060d4af
--- /dev/null
+++ b/src/commands/cluster-replicate.json
@@ -0,0 +1,25 @@
+{
+ "REPLICATE": {
+ "summary": "Configure a node as replica of a master node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "node-id",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-reset.json b/src/commands/cluster-reset.json
new file mode 100644
index 0000000..6bd4fe6
--- /dev/null
+++ b/src/commands/cluster-reset.json
@@ -0,0 +1,38 @@
+{
+ "RESET": {
+ "summary": "Resets a node.",
+ "complexity": "O(N) where N is the number of known nodes. The command may execute a FLUSHALL as a side effect.",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "ADMIN",
+ "STALE",
+ "NOSCRIPT"
+ ],
+ "arguments": [
+ {
+ "name": "reset-type",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "hard",
+ "type": "pure-token",
+ "token": "HARD"
+ },
+ {
+ "name": "soft",
+ "type": "pure-token",
+ "token": "SOFT"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-saveconfig.json b/src/commands/cluster-saveconfig.json
new file mode 100644
index 0000000..d004509
--- /dev/null
+++ b/src/commands/cluster-saveconfig.json
@@ -0,0 +1,19 @@
+{
+ "SAVECONFIG": {
+ "summary": "Forces a node to save the cluster configuration to disk.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-set-config-epoch.json b/src/commands/cluster-set-config-epoch.json
new file mode 100644
index 0000000..70c7de4
--- /dev/null
+++ b/src/commands/cluster-set-config-epoch.json
@@ -0,0 +1,25 @@
+{
+ "SET-CONFIG-EPOCH": {
+ "summary": "Sets the configuration epoch for a new node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "config-epoch",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-setslot.json b/src/commands/cluster-setslot.json
new file mode 100644
index 0000000..d0d4819
--- /dev/null
+++ b/src/commands/cluster-setslot.json
@@ -0,0 +1,54 @@
+{
+ "SETSLOT": {
+ "summary": "Binds a hash slot to a node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -4,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "slot",
+ "type": "integer"
+ },
+ {
+ "name": "subcommand",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "importing",
+ "display": "node-id",
+ "type": "string",
+ "token": "IMPORTING"
+ },
+ {
+ "name": "migrating",
+ "display": "node-id",
+ "type": "string",
+ "token": "MIGRATING"
+ },
+ {
+ "name": "node",
+ "display": "node-id",
+ "type": "string",
+ "token": "NODE"
+ },
+ {
+ "name": "stable",
+ "type": "pure-token",
+ "token": "STABLE"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/cluster-shards.json b/src/commands/cluster-shards.json
new file mode 100644
index 0000000..e7a0829
--- /dev/null
+++ b/src/commands/cluster-shards.json
@@ -0,0 +1,90 @@
+{
+ "SHARDS": {
+ "summary": "Returns the mapping of cluster slots to shards.",
+ "complexity": "O(N) where N is the total number of cluster nodes",
+ "group": "cluster",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "history": [],
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "a nested list of a map of hash ranges and shard nodes describing individual shards",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "slots": {
+ "description": "an even number element array specifying the start and end slot numbers for slot ranges owned by this shard",
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "nodes": {
+ "description": "nodes that handle these slot ranges",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "tls-port": {
+ "type": "integer"
+ },
+ "ip": {
+ "type": "string"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "role": {
+ "oneOf": [
+ {
+ "const": "master"
+ },
+ {
+ "const": "replica"
+ }
+ ]
+ },
+ "replication-offset": {
+ "type": "integer"
+ },
+ "health": {
+ "oneOf": [
+ {
+ "const": "fail"
+ },
+ {
+ "const": "loading"
+ },
+ {
+ "const": "online"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-slaves.json b/src/commands/cluster-slaves.json
new file mode 100644
index 0000000..a736088
--- /dev/null
+++ b/src/commands/cluster-slaves.json
@@ -0,0 +1,37 @@
+{
+ "SLAVES": {
+ "summary": "Lists the replica nodes of a master node.",
+ "complexity": "O(N) where N is the number of replicas.",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 3,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "deprecated_since": "5.0.0",
+ "replaced_by": "`CLUSTER REPLICAS`",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "ADMIN",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "arguments": [
+ {
+ "name": "node-id",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "a list of replica nodes replicating from the specified master node provided in the same format used by CLUSTER NODES",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "description": "the serialized cluster configuration"
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster-slots.json b/src/commands/cluster-slots.json
new file mode 100644
index 0000000..b00cc60
--- /dev/null
+++ b/src/commands/cluster-slots.json
@@ -0,0 +1,136 @@
+{
+ "SLOTS": {
+ "summary": "Returns the mapping of cluster slots to nodes.",
+ "complexity": "O(N) where N is the total number of Cluster nodes",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 2,
+ "container": "CLUSTER",
+ "function": "clusterCommand",
+ "deprecated_since": "7.0.0",
+ "replaced_by": "`CLUSTER SHARDS`",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "history": [
+ [
+ "4.0.0",
+ "Added node IDs."
+ ],
+ [
+ "7.0.0",
+ "Added additional networking metadata field."
+ ]
+ ],
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "description": "nested list of slot ranges with networking information",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 4294967295,
+ "items": [
+ {
+ "description": "start slot number",
+ "type": "integer"
+ },
+ {
+ "description": "end slot number",
+ "type": "integer"
+ },
+ {
+ "type": "array",
+ "description": "Master node for the slot range",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "endpoint description",
+ "oneOf": [
+ {
+ "description": "hostname or ip",
+ "type": "string"
+ },
+ {
+ "description": "unknown type",
+ "type": "null"
+ }
+ ]
+ },
+ {
+ "description": "port",
+ "type": "integer"
+ },
+ {
+ "description": "node name",
+ "type": "string"
+ },
+ {
+ "description": "array of node descriptions",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "hostname": {
+ "type": "string"
+ },
+ "ip": {
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "additionalItems": {
+ "type": "array",
+ "description": "Replica node for the slot range",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "endpoint description",
+ "oneOf": [
+ {
+ "description": "hostname or ip",
+ "type": "string"
+ },
+ {
+ "description": "unknown type",
+ "type": "null"
+ }
+ ]
+ },
+ {
+ "description": "port",
+ "type": "integer"
+ },
+ {
+ "description": "node name",
+ "type": "string"
+ },
+ {
+ "description": "array of node descriptions",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "hostname": {
+ "type": "string"
+ },
+ "ip": {
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/cluster.json b/src/commands/cluster.json
new file mode 100644
index 0000000..e74404d
--- /dev/null
+++ b/src/commands/cluster.json
@@ -0,0 +1,9 @@
+{
+ "CLUSTER": {
+ "summary": "A container for Redis Cluster commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/command-count.json b/src/commands/command-count.json
new file mode 100644
index 0000000..7306767
--- /dev/null
+++ b/src/commands/command-count.json
@@ -0,0 +1,23 @@
+{
+ "COUNT": {
+ "summary": "Returns a count of commands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 2,
+ "container": "COMMAND",
+ "function": "commandCountCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "description": "Number of total commands in this Redis server.",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/command-docs.json b/src/commands/command-docs.json
new file mode 100644
index 0000000..75df5b4
--- /dev/null
+++ b/src/commands/command-docs.json
@@ -0,0 +1,211 @@
+{
+ "DOCS": {
+ "summary": "Returns documentary information about one, multiple or all commands.",
+ "complexity": "O(N) where N is the number of commands to look up",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "COMMAND",
+ "function": "commandDocsCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "reply_schema": {
+ "description": "A map where each key is a command name, and each value is the documentary information",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "summary": {
+ "description": "short command description",
+ "type": "string"
+ },
+ "since": {
+ "description": "the Redis version that added the command (or for module commands, the module version).",
+ "type": "string"
+ },
+ "group": {
+ "description": "the functional group to which the command belongs",
+ "oneOf": [
+ {
+ "const": "bitmap"
+ },
+ {
+ "const": "cluster"
+ },
+ {
+ "const": "connection"
+ },
+ {
+ "const": "generic"
+ },
+ {
+ "const": "geo"
+ },
+ {
+ "const": "hash"
+ },
+ {
+ "const": "hyperloglog"
+ },
+ {
+ "const": "list"
+ },
+ {
+ "const": "module"
+ },
+ {
+ "const": "pubsub"
+ },
+ {
+ "const": "scripting"
+ },
+ {
+ "const": "sentinel"
+ },
+ {
+ "const": "server"
+ },
+ {
+ "const": "set"
+ },
+ {
+ "const": "sorted-set"
+ },
+ {
+ "const": "stream"
+ },
+ {
+ "const": "string"
+ },
+ {
+ "const": "transactions"
+ }
+ ]
+ },
+ "complexity": {
+ "description": "a short explanation about the command's time complexity.",
+ "type": "string"
+ },
+ "module": {
+ "type": "string"
+ },
+ "doc_flags": {
+ "description": "an array of documentation flags",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "description": "the command is deprecated.",
+ "const": "deprecated"
+ },
+ {
+ "description": "a system command that isn't meant to be called by users.",
+ "const": "syscmd"
+ }
+ ]
+ }
+ },
+ "deprecated_since": {
+ "description": "the Redis version that deprecated the command (or for module commands, the module version)",
+ "type": "string"
+ },
+ "replaced_by": {
+ "description": "the alternative for a deprecated command.",
+ "type": "string"
+ },
+ "history": {
+ "description": "an array of historical notes describing changes to the command's behavior or arguments.",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "The Redis version that the entry applies to."
+ },
+ {
+ "type": "string",
+ "description": "The description of the change."
+ }
+ ]
+ }
+ },
+ "arguments": {
+ "description": "an array of maps that describe the command's arguments.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "display_text": {
+ "type": "string"
+ },
+ "key_spec_index": {
+ "type": "integer"
+ },
+ "token": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ },
+ "since": {
+ "type": "string"
+ },
+ "deprecated_since": {
+ "type": "string"
+ },
+ "flags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "reply_schema": {
+ "description": "command reply schema",
+ "type": "object"
+ },
+ "subcommands": {
+ "description": "A map where each key is a subcommand, and each value is the documentary information",
+ "$ref": "#"
+ }
+ }
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "command-name",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/command-getkeys.json b/src/commands/command-getkeys.json
new file mode 100644
index 0000000..88103c5
--- /dev/null
+++ b/src/commands/command-getkeys.json
@@ -0,0 +1,39 @@
+{
+ "GETKEYS": {
+ "summary": "Extracts the key names from an arbitrary command.",
+ "complexity": "O(N) where N is the number of arguments to the command",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": -3,
+ "container": "COMMAND",
+ "function": "commandGetKeysCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "description": "List of keys from the given Redis command.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ },
+ "arguments": [
+ {
+ "name": "command",
+ "type": "string"
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/command-getkeysandflags.json b/src/commands/command-getkeysandflags.json
new file mode 100644
index 0000000..a069f5e
--- /dev/null
+++ b/src/commands/command-getkeysandflags.json
@@ -0,0 +1,55 @@
+{
+ "GETKEYSANDFLAGS": {
+ "summary": "Extracts the key names and access flags for an arbitrary command.",
+ "complexity": "O(N) where N is the number of arguments to the command",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -3,
+ "container": "COMMAND",
+ "function": "commandGetKeysAndFlagsCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "description": "List of keys from the given Redis command and their usage flags.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Key name",
+ "type": "string"
+ },
+ {
+ "description": "Set of key flags",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "command",
+ "type": "string"
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/command-help.json b/src/commands/command-help.json
new file mode 100644
index 0000000..5735f01
--- /dev/null
+++ b/src/commands/command-help.json
@@ -0,0 +1,26 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "COMMAND",
+ "function": "commandHelpCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/command-info.json b/src/commands/command-info.json
new file mode 100644
index 0000000..8c69060
--- /dev/null
+++ b/src/commands/command-info.json
@@ -0,0 +1,213 @@
+{
+ "INFO": {
+ "summary": "Returns information about one, multiple or all commands.",
+ "complexity": "O(N) where N is the number of commands to look up",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": -2,
+ "container": "COMMAND",
+ "function": "commandInfoCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Allowed to be called with no argument to get info on all commands."
+ ]
+ ],
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "arguments": [
+ {
+ "name": "command-name",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "description": "command does not exist",
+ "type": "null"
+ },
+ {
+ "description": "command info array output",
+ "type": "array",
+ "minItems": 10,
+ "maxItems": 10,
+ "items": [
+ {
+ "description": "command name",
+ "type": "string"
+ },
+ {
+ "description": "command arity",
+ "type": "integer"
+ },
+ {
+ "description": "command flags",
+ "type": "array",
+ "items": {
+ "description": "command flag",
+ "type": "string"
+ }
+ },
+ {
+ "description": "command first key index",
+ "type": "integer"
+ },
+ {
+ "description": "command last key index",
+ "type": "integer"
+ },
+ {
+ "description": "command key step index",
+ "type": "integer"
+ },
+ {
+ "description": "command categories",
+ "type": "array",
+ "items": {
+ "description": "command category",
+ "type": "string"
+ }
+ },
+ {
+ "description": "command tips",
+ "type": "array",
+ "items": {
+ "description": "command tip",
+ "type": "string"
+ }
+ },
+ {
+ "description": "command key specs",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "notes": {
+ "type": "string"
+ },
+ "flags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "begin_search": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "spec": {
+ "anyOf": [
+ {
+ "description": "unknown type, empty map",
+ "type": "object",
+ "additionalProperties": false
+ },
+ {
+ "description": "index type",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "index": {
+ "type": "integer"
+ }
+ }
+ },
+ {
+ "description": "keyword type",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keyword": {
+ "type": "string"
+ },
+ "startfrom": {
+ "type": "integer"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "find_keys": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "spec": {
+ "anyOf": [
+ {
+ "description": "unknown type",
+ "type": "object",
+ "additionalProperties": false
+ },
+ {
+ "description": "range type",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lastkey": {
+ "type": "integer"
+ },
+ "keystep": {
+ "type": "integer"
+ },
+ "limit": {
+ "type": "integer"
+ }
+ }
+ },
+ {
+ "description": "keynum type",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keynumidx": {
+ "type": "integer"
+ },
+ "firstkey": {
+ "type": "integer"
+ },
+ "keystep": {
+ "type": "integer"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "array",
+ "description": "subcommands"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/command-list.json b/src/commands/command-list.json
new file mode 100644
index 0000000..b85a9a5
--- /dev/null
+++ b/src/commands/command-list.json
@@ -0,0 +1,55 @@
+{
+ "LIST": {
+ "summary": "Returns a list of command names.",
+ "complexity": "O(N) where N is the total number of Redis commands",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "COMMAND",
+ "function": "commandListCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "arguments": [
+ {
+ "name": "filterby",
+ "token": "FILTERBY",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "module-name",
+ "type": "string",
+ "token": "MODULE"
+ },
+ {
+ "name": "category",
+ "type": "string",
+ "token": "ACLCAT"
+ },
+ {
+ "name": "pattern",
+ "type": "pattern",
+ "token": "PATTERN"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "description": "command name",
+ "type": "string"
+ },
+ "uniqueItems": true
+ }
+ }
+}
diff --git a/src/commands/command.json b/src/commands/command.json
new file mode 100644
index 0000000..9d15be2
--- /dev/null
+++ b/src/commands/command.json
@@ -0,0 +1,21 @@
+{
+ "COMMAND": {
+ "summary": "Returns detailed information about all commands.",
+ "complexity": "O(N) where N is the total number of Redis commands",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": -1,
+ "function": "commandCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ]
+ }
+}
diff --git a/src/commands/config-get.json b/src/commands/config-get.json
new file mode 100644
index 0000000..53f2d85
--- /dev/null
+++ b/src/commands/config-get.json
@@ -0,0 +1,36 @@
+{
+ "GET": {
+ "summary": "Returns the effective values of configuration parameters.",
+ "complexity": "O(N) when N is the number of configuration parameters provided",
+ "group": "server",
+ "since": "2.0.0",
+ "arity": -3,
+ "container": "CONFIG",
+ "function": "configGetCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the ability to pass multiple pattern parameters in one call"
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "parameter",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/config-help.json b/src/commands/config-help.json
new file mode 100644
index 0000000..da3e9c4
--- /dev/null
+++ b/src/commands/config-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "CONFIG",
+ "function": "configHelpCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/config-resetstat.json b/src/commands/config-resetstat.json
new file mode 100644
index 0000000..fd6701f
--- /dev/null
+++ b/src/commands/config-resetstat.json
@@ -0,0 +1,24 @@
+{
+ "RESETSTAT": {
+ "summary": "Resets the server's statistics.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.0.0",
+ "arity": 2,
+ "container": "CONFIG",
+ "function": "configResetStatCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/config-rewrite.json b/src/commands/config-rewrite.json
new file mode 100644
index 0000000..af49dd7
--- /dev/null
+++ b/src/commands/config-rewrite.json
@@ -0,0 +1,24 @@
+{
+ "REWRITE": {
+ "summary": "Persists the effective configuration to file.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.0",
+ "arity": 2,
+ "container": "CONFIG",
+ "function": "configRewriteCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/config-set.json b/src/commands/config-set.json
new file mode 100644
index 0000000..83f2461
--- /dev/null
+++ b/src/commands/config-set.json
@@ -0,0 +1,47 @@
+{
+ "SET": {
+ "summary": "Sets configuration parameters in-flight.",
+ "complexity": "O(N) when N is the number of configuration parameters provided",
+ "group": "server",
+ "since": "2.0.0",
+ "arity": -4,
+ "container": "CONFIG",
+ "function": "configSetCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the ability to set multiple parameters in one call."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "parameter",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/config.json b/src/commands/config.json
new file mode 100644
index 0000000..1c4457a
--- /dev/null
+++ b/src/commands/config.json
@@ -0,0 +1,9 @@
+{
+ "CONFIG": {
+ "summary": "A container for server configuration commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "2.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/copy.json b/src/commands/copy.json
new file mode 100644
index 0000000..b30ddae
--- /dev/null
+++ b/src/commands/copy.json
@@ -0,0 +1,91 @@
+{
+ "COPY": {
+ "summary": "Copies the value of a key to a new key.",
+ "complexity": "O(N) worst case for collections, where N is the number of nested items. O(1) for string values.",
+ "group": "generic",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "copyCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "token": "DB",
+ "name": "destination-db",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "replace",
+ "token": "REPLACE",
+ "type": "pure-token",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "source was copied",
+ "const": 1
+ },
+ {
+ "description": "source was not copied",
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/dbsize.json b/src/commands/dbsize.json
new file mode 100644
index 0000000..249df41
--- /dev/null
+++ b/src/commands/dbsize.json
@@ -0,0 +1,25 @@
+{
+ "DBSIZE": {
+ "summary": "Returns the number of keys in the database.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "dbsizeCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of keys in the currently-selected database."
+ }
+ }
+}
diff --git a/src/commands/debug.json b/src/commands/debug.json
new file mode 100644
index 0000000..1646d7b
--- /dev/null
+++ b/src/commands/debug.json
@@ -0,0 +1,20 @@
+{
+ "DEBUG": {
+ "summary": "A container for debugging commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "debugCommand",
+ "doc_flags": [
+ "SYSCMD"
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "PROTECTED"
+ ]
+ }
+}
diff --git a/src/commands/decr.json b/src/commands/decr.json
new file mode 100644
index 0000000..0841928
--- /dev/null
+++ b/src/commands/decr.json
@@ -0,0 +1,50 @@
+{
+ "DECR": {
+ "summary": "Decrements the integer value of a key by one. Uses 0 as initial value if the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "decrCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The value of the key after decrementing it."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/decrby.json b/src/commands/decrby.json
new file mode 100644
index 0000000..3db9879
--- /dev/null
+++ b/src/commands/decrby.json
@@ -0,0 +1,54 @@
+{
+ "DECRBY": {
+ "summary": "Decrements a number from the integer value of a key. Uses 0 as initial value if the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "decrbyCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The value of the key after decrementing it."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "decrement",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/del.json b/src/commands/del.json
new file mode 100644
index 0000000..2727b53
--- /dev/null
+++ b/src/commands/del.json
@@ -0,0 +1,53 @@
+{
+ "DEL": {
+ "summary": "Deletes one or more keys.",
+ "complexity": "O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "delCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RM",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of keys that were removed",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/discard.json b/src/commands/discard.json
new file mode 100644
index 0000000..ffd37f0
--- /dev/null
+++ b/src/commands/discard.json
@@ -0,0 +1,23 @@
+{
+ "DISCARD": {
+ "summary": "Discards a transaction.",
+ "complexity": "O(N), when N is the number of queued commands",
+ "group": "transactions",
+ "since": "2.0.0",
+ "arity": 1,
+ "function": "discardCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "TRANSACTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/dump.json b/src/commands/dump.json
new file mode 100644
index 0000000..9e772ed
--- /dev/null
+++ b/src/commands/dump.json
@@ -0,0 +1,58 @@
+{
+ "DUMP": {
+ "summary": "Returns a serialized representation of the value stored at a key.",
+ "complexity": "O(1) to access the key and additional O(N*M) to serialize it, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1).",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": 2,
+ "function": "dumpCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The serialized value.",
+ "type": "string"
+ },
+ {
+ "description": "Key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/echo.json b/src/commands/echo.json
new file mode 100644
index 0000000..df87198
--- /dev/null
+++ b/src/commands/echo.json
@@ -0,0 +1,28 @@
+{
+ "ECHO": {
+ "summary": "Returns the given string.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "echoCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "description": "The given string",
+ "type": "string"
+ },
+ "arguments": [
+ {
+ "name": "message",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/eval.json b/src/commands/eval.json
new file mode 100644
index 0000000..05e1cb5
--- /dev/null
+++ b/src/commands/eval.json
@@ -0,0 +1,69 @@
+{
+ "EVAL": {
+ "summary": "Executes a server-side Lua script.",
+ "complexity": "Depends on the script that is executed.",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": -3,
+ "function": "evalCommand",
+ "get_keys_function": "evalGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "MAY_REPLICATE",
+ "NO_MANDATORY_KEYS",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "notes": "We cannot tell how the keys will be used so we assume the worst, RW and UPDATE",
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "script",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the script that is executed"
+ }
+ }
+}
diff --git a/src/commands/eval_ro.json b/src/commands/eval_ro.json
new file mode 100644
index 0000000..1440998
--- /dev/null
+++ b/src/commands/eval_ro.json
@@ -0,0 +1,68 @@
+{
+ "EVAL_RO": {
+ "summary": "Executes a read-only server-side Lua script.",
+ "complexity": "Depends on the script that is executed.",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "evalRoCommand",
+ "get_keys_function": "evalGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "NO_MANDATORY_KEYS",
+ "STALE",
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "notes": "We cannot tell how the keys will be used so we assume the worst, RO and ACCESS",
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "script",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional":true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional":true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the script that is executed"
+ }
+ }
+}
diff --git a/src/commands/evalsha.json b/src/commands/evalsha.json
new file mode 100644
index 0000000..c7d0aa7
--- /dev/null
+++ b/src/commands/evalsha.json
@@ -0,0 +1,68 @@
+{
+ "EVALSHA": {
+ "summary": "Executes a server-side Lua script by SHA1 digest.",
+ "complexity": "Depends on the script that is executed.",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": -3,
+ "function": "evalShaCommand",
+ "get_keys_function": "evalGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "MAY_REPLICATE",
+ "NO_MANDATORY_KEYS",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "sha1",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the script that is executed"
+ }
+ }
+}
diff --git a/src/commands/evalsha_ro.json b/src/commands/evalsha_ro.json
new file mode 100644
index 0000000..51e4dab
--- /dev/null
+++ b/src/commands/evalsha_ro.json
@@ -0,0 +1,67 @@
+{
+ "EVALSHA_RO": {
+ "summary": "Executes a read-only server-side Lua script by SHA1 digest.",
+ "complexity": "Depends on the script that is executed.",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "evalShaRoCommand",
+ "get_keys_function": "evalGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "NO_MANDATORY_KEYS",
+ "STALE",
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "sha1",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional":true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional":true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the script that is executed"
+ }
+ }
+}
diff --git a/src/commands/exec.json b/src/commands/exec.json
new file mode 100644
index 0000000..5f03d76
--- /dev/null
+++ b/src/commands/exec.json
@@ -0,0 +1,31 @@
+{
+ "EXEC": {
+ "summary": "Executes all commands in a transaction.",
+ "complexity": "Depends on commands in the transaction",
+ "group": "transactions",
+ "since": "1.2.0",
+ "arity": 1,
+ "function": "execCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SKIP_SLOWLOG"
+ ],
+ "acl_categories": [
+ "TRANSACTION"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Each element being the reply to each of the commands in the atomic transaction.",
+ "type": "array"
+ },
+ {
+ "description": "The transaction was aborted because a `WATCH`ed key was touched",
+ "type": "null"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/exists.json b/src/commands/exists.json
new file mode 100644
index 0000000..8b108bc
--- /dev/null
+++ b/src/commands/exists.json
@@ -0,0 +1,58 @@
+{
+ "EXISTS": {
+ "summary": "Determines whether one or more keys exist.",
+ "complexity": "O(N) where N is the number of keys to check.",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "existsCommand",
+ "history": [
+ [
+ "3.0.3",
+ "Accepts multiple `key` arguments."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of keys that exist from those specified as arguments.",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/expire.json b/src/commands/expire.json
new file mode 100644
index 0000000..bf80939
--- /dev/null
+++ b/src/commands/expire.json
@@ -0,0 +1,94 @@
+{
+ "EXPIRE": {
+ "summary": "Sets the expiration time of a key in seconds.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "expireCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added options: `NX`, `XX`, `GT` and `LT`."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments.",
+ "const": 0
+ },
+ {
+ "description": "The timeout was set.",
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "seconds",
+ "type": "integer"
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ },
+ {
+ "name": "gt",
+ "type": "pure-token",
+ "token": "GT"
+ },
+ {
+ "name": "lt",
+ "type": "pure-token",
+ "token": "LT"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/expireat.json b/src/commands/expireat.json
new file mode 100644
index 0000000..c2ba5d8
--- /dev/null
+++ b/src/commands/expireat.json
@@ -0,0 +1,94 @@
+{
+ "EXPIREAT": {
+ "summary": "Sets the expiration time of a key to a Unix timestamp.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.2.0",
+ "arity": -3,
+ "function": "expireatCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added options: `NX`, `XX`, `GT` and `LT`."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 1,
+ "description": "The timeout was set."
+ },
+ {
+ "const": 0,
+ "description": "The timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "unix-time-seconds",
+ "type": "unix-time"
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ },
+ {
+ "name": "gt",
+ "type": "pure-token",
+ "token": "GT"
+ },
+ {
+ "name": "lt",
+ "type": "pure-token",
+ "token": "LT"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/expiretime.json b/src/commands/expiretime.json
new file mode 100644
index 0000000..99da9d2
--- /dev/null
+++ b/src/commands/expiretime.json
@@ -0,0 +1,61 @@
+{
+ "EXPIRETIME": {
+ "summary": "Returns the expiration time of a key as a Unix timestamp.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "7.0.0",
+ "arity": 2,
+ "function": "expiretimeCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "integer",
+ "description": "Expiration Unix timestamp in seconds.",
+ "minimum": 0
+ },
+ {
+ "const": -1,
+ "description": "The key exists but has no associated expiration time."
+ },
+ {
+ "const": -2,
+ "description": "The key does not exist."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/failover.json b/src/commands/failover.json
new file mode 100644
index 0000000..c694862
--- /dev/null
+++ b/src/commands/failover.json
@@ -0,0 +1,54 @@
+{
+ "FAILOVER": {
+ "summary": "Starts a coordinated failover from a server to one of its replicas.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "6.2.0",
+ "arity": -1,
+ "function": "failoverCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "STALE"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "target",
+ "token": "TO",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "host",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ },
+ {
+ "token": "FORCE",
+ "name": "force",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "token": "ABORT",
+ "name": "abort",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "TIMEOUT",
+ "name": "milliseconds",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/fcall.json b/src/commands/fcall.json
new file mode 100644
index 0000000..7d6be69
--- /dev/null
+++ b/src/commands/fcall.json
@@ -0,0 +1,69 @@
+{
+ "FCALL": {
+ "summary": "Invokes a function.",
+ "complexity": "Depends on the function that is executed.",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "fcallCommand",
+ "get_keys_function": "functionGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "MAY_REPLICATE",
+ "NO_MANDATORY_KEYS",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "notes": "We cannot tell how the keys will be used so we assume the worst, RW and UPDATE",
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "function",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the function that is executed"
+ }
+ }
+}
diff --git a/src/commands/fcall_ro.json b/src/commands/fcall_ro.json
new file mode 100644
index 0000000..d0e4c76
--- /dev/null
+++ b/src/commands/fcall_ro.json
@@ -0,0 +1,68 @@
+{
+ "FCALL_RO": {
+ "summary": "Invokes a read-only function.",
+ "complexity": "Depends on the function that is executed.",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "fcallroCommand",
+ "get_keys_function": "functionGetKeys",
+ "command_flags": [
+ "NOSCRIPT",
+ "SKIP_MONITOR",
+ "NO_MANDATORY_KEYS",
+ "STALE",
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "key_specs": [
+ {
+ "notes": "We cannot tell how the keys will be used so we assume the worst, RO and ACCESS",
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "function",
+ "type": "string"
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Return value depends on the function that is executed"
+ }
+ }
+}
diff --git a/src/commands/flushall.json b/src/commands/flushall.json
new file mode 100644
index 0000000..304bd03
--- /dev/null
+++ b/src/commands/flushall.json
@@ -0,0 +1,55 @@
+{
+ "FLUSHALL": {
+ "summary": "Removes all keys from all databases.",
+ "complexity": "O(N) where N is the total number of keys in all databases",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "flushallCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Added the `ASYNC` flushing mode modifier."
+ ],
+ [
+ "6.2.0",
+ "Added the `SYNC` flushing mode modifier."
+ ]
+ ],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "flush-type",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "async",
+ "type": "pure-token",
+ "token": "ASYNC",
+ "since": "4.0.0"
+ },
+ {
+ "name": "sync",
+ "type": "pure-token",
+ "token": "SYNC",
+ "since": "6.2.0"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/flushdb.json b/src/commands/flushdb.json
new file mode 100644
index 0000000..f1d10b8
--- /dev/null
+++ b/src/commands/flushdb.json
@@ -0,0 +1,55 @@
+{
+ "FLUSHDB": {
+ "summary": "Remove all keys from the current database.",
+ "complexity": "O(N) where N is the number of keys in the selected database",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "flushdbCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Added the `ASYNC` flushing mode modifier."
+ ],
+ [
+ "6.2.0",
+ "Added the `SYNC` flushing mode modifier."
+ ]
+ ],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "flush-type",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "async",
+ "type": "pure-token",
+ "token": "ASYNC",
+ "since": "4.0.0"
+ },
+ {
+ "name": "sync",
+ "type": "pure-token",
+ "token": "SYNC",
+ "since": "6.2.0"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/function-delete.json b/src/commands/function-delete.json
new file mode 100644
index 0000000..0895457
--- /dev/null
+++ b/src/commands/function-delete.json
@@ -0,0 +1,31 @@
+{
+ "DELETE": {
+ "summary": "Deletes a library and its functions.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": 3,
+ "container": "FUNCTION",
+ "function": "functionDeleteCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "library-name",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/function-dump.json b/src/commands/function-dump.json
new file mode 100644
index 0000000..d117241
--- /dev/null
+++ b/src/commands/function-dump.json
@@ -0,0 +1,21 @@
+{
+ "DUMP": {
+ "summary": "Dumps all libraries into a serialized binary payload.",
+ "complexity": "O(N) where N is the number of functions",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "FUNCTION",
+ "function": "functionDumpCommand",
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "reply_schema": {
+ "description": "the serialized payload",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/function-flush.json b/src/commands/function-flush.json
new file mode 100644
index 0000000..58742a0
--- /dev/null
+++ b/src/commands/function-flush.json
@@ -0,0 +1,44 @@
+{
+ "FLUSH": {
+ "summary": "Deletes all libraries and functions.",
+ "complexity": "O(N) where N is the number of functions deleted",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "FUNCTION",
+ "function": "functionFlushCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "flush-type",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "async",
+ "type": "pure-token",
+ "token": "ASYNC"
+ },
+ {
+ "name": "sync",
+ "type": "pure-token",
+ "token": "SYNC"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/function-help.json b/src/commands/function-help.json
new file mode 100644
index 0000000..662e7e6
--- /dev/null
+++ b/src/commands/function-help.json
@@ -0,0 +1,25 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "FUNCTION",
+ "function": "functionHelpCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/function-kill.json b/src/commands/function-kill.json
new file mode 100644
index 0000000..396370c
--- /dev/null
+++ b/src/commands/function-kill.json
@@ -0,0 +1,25 @@
+{
+ "KILL": {
+ "summary": "Terminates a function during execution.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "FUNCTION",
+ "function": "functionKillCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ONE_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/function-list.json b/src/commands/function-list.json
new file mode 100644
index 0000000..2ab1cf5
--- /dev/null
+++ b/src/commands/function-list.json
@@ -0,0 +1,87 @@
+{
+ "LIST": {
+ "summary": "Returns information about all libraries.",
+ "complexity": "O(N) where N is the number of functions",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "FUNCTION",
+ "function": "functionListCommand",
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "library_name": {
+ "description": " the name of the library",
+ "type": "string"
+ },
+ "engine": {
+ "description": "the engine of the library",
+ "type": "string"
+ },
+ "functions": {
+ "description": "the list of functions in the library",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "the name of the function",
+ "type": "string"
+ },
+ "description": {
+ "description": "the function's description",
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "flags": {
+ "description": "an array of function flags",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "library_code": {
+ "description": "the library's source code (when given the WITHCODE modifier)",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "library-name-pattern",
+ "type": "string",
+ "token": "LIBRARYNAME",
+ "optional": true
+ },
+ {
+ "name": "withcode",
+ "type": "pure-token",
+ "token": "WITHCODE",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/function-load.json b/src/commands/function-load.json
new file mode 100644
index 0000000..f918b65
--- /dev/null
+++ b/src/commands/function-load.json
@@ -0,0 +1,39 @@
+{
+ "LOAD": {
+ "summary": "Creates a library.",
+ "complexity": "O(1) (considering compilation time is redundant)",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "container": "FUNCTION",
+ "function": "functionLoadCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "replace",
+ "type": "pure-token",
+ "token": "REPLACE",
+ "optional": true
+ },
+ {
+ "name": "function-code",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The library name that was loaded",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/function-restore.json b/src/commands/function-restore.json
new file mode 100644
index 0000000..0c37004
--- /dev/null
+++ b/src/commands/function-restore.json
@@ -0,0 +1,54 @@
+{
+ "RESTORE": {
+ "summary": "Restores all libraries from a payload.",
+ "complexity": "O(N) where N is the number of functions on the payload",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -3,
+ "container": "FUNCTION",
+ "function": "functionRestoreCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "serialized-value",
+ "type": "string"
+ },
+ {
+ "name": "policy",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "flush",
+ "type": "pure-token",
+ "token": "FLUSH"
+ },
+ {
+ "name": "append",
+ "type": "pure-token",
+ "token": "APPEND"
+ },
+ {
+ "name": "replace",
+ "type": "pure-token",
+ "token": "REPLACE"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/function-stats.json b/src/commands/function-stats.json
new file mode 100644
index 0000000..65519db
--- /dev/null
+++ b/src/commands/function-stats.json
@@ -0,0 +1,81 @@
+{
+ "STATS": {
+ "summary": "Returns information about a function during execution.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": 2,
+ "container": "FUNCTION",
+ "function": "functionStatsCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "running_script": {
+ "description": "information about the running script.",
+ "oneOf": [
+ {
+ "description": "If there's no in-flight function",
+ "type": "null"
+ },
+ {
+ "description": "a map with the information about the running script",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "the name of the function.",
+ "type": "string"
+ },
+ "command": {
+ "description": "the command and arguments used for invoking the function.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "duration_ms": {
+ "description": "the function's runtime duration in milliseconds.",
+ "type": "integer"
+ }
+ }
+ }
+ ]
+ },
+ "engines": {
+ "description": "A map when each entry in the map represent a single engine.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "description": "Engine map contains statistics about the engine",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "libraries_count": {
+ "description": "number of libraries",
+ "type": "integer"
+ },
+ "functions_count": {
+ "description": "number of functions",
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/function.json b/src/commands/function.json
new file mode 100644
index 0000000..c474137
--- /dev/null
+++ b/src/commands/function.json
@@ -0,0 +1,9 @@
+{
+ "FUNCTION": {
+ "summary": "A container for function commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "scripting",
+ "since": "7.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/geoadd.json b/src/commands/geoadd.json
new file mode 100644
index 0000000..5409bfc
--- /dev/null
+++ b/src/commands/geoadd.json
@@ -0,0 +1,98 @@
+{
+ "GEOADD": {
+ "summary": "Adds one or more members to a geospatial index. The key is created if it doesn't exist.",
+ "complexity": "O(log(N)) for each item added, where N is the number of elements in the sorted set.",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -5,
+ "function": "geoaddCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `CH`, `NX` and `XX` options."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ }
+ ]
+ },
+ {
+ "name": "change",
+ "token": "CH",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "longitude",
+ "type": "double"
+ },
+ {
+ "name": "latitude",
+ "type": "double"
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "When used without optional arguments, the number of elements added to the sorted set (excluding score updates). If the CH option is specified, the number of elements that were changed (added or updated).",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/geodist.json b/src/commands/geodist.json
new file mode 100644
index 0000000..145ca71
--- /dev/null
+++ b/src/commands/geodist.json
@@ -0,0 +1,91 @@
+{
+ "GEODIST": {
+ "summary": "Returns the distance between two members of a geospatial index.",
+ "complexity": "O(1)",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -4,
+ "function": "geodistCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member1",
+ "type": "string"
+ },
+ {
+ "name": "member2",
+ "type": "string"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "one or both of elements are missing",
+ "type": "null"
+ },
+ {
+ "description": "distance as a double (represented as a string) in the specified units",
+ "type": "string",
+ "pattern": "^[0-9]*(.[0-9]*)?$"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/geohash.json b/src/commands/geohash.json
new file mode 100644
index 0000000..01402c4
--- /dev/null
+++ b/src/commands/geohash.json
@@ -0,0 +1,56 @@
+{
+ "GEOHASH": {
+ "summary": "Returns members from a geospatial index as geohash strings.",
+ "complexity": "O(1) for each member requested.",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -2,
+ "function": "geohashCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true,
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "An array where each element is the Geohash corresponding to each member name passed as argument to the command.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/geopos.json b/src/commands/geopos.json
new file mode 100644
index 0000000..408b6e6
--- /dev/null
+++ b/src/commands/geopos.json
@@ -0,0 +1,76 @@
+{
+ "GEOPOS": {
+ "summary": "Returns the longitude and latitude of members from a geospatial index.",
+ "complexity": "O(1) for each member requested.",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -2,
+ "function": "geoposCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true,
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "An array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "description": "Element does not exist",
+ "type": "null"
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "Longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/georadius.json b/src/commands/georadius.json
new file mode 100644
index 0000000..6ced904
--- /dev/null
+++ b/src/commands/georadius.json
@@ -0,0 +1,270 @@
+{
+ "GEORADIUS": {
+ "summary": "Queries a geospatial index for members within a distance from a coordinate, optionally stores the result.",
+ "complexity": "O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -6,
+ "function": "georadiusCommand",
+ "get_keys_function": "georadiusGetKeys",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `ANY` option for `COUNT`."
+ ],
+ [
+ "7.0.0",
+ "Added support for uppercase unit names."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`GEOSEARCH` and `GEOSEARCHSTORE` with the `BYRADIUS` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STORE",
+ "startfrom": 6
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STOREDIST",
+ "startfrom": 6
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "longitude",
+ "type": "double"
+ },
+ {
+ "name": "latitude",
+ "type": "double"
+ },
+ {
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ },
+ {
+ "name": "withcoord",
+ "token": "WITHCOORD",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withdist",
+ "token": "WITHDIST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withhash",
+ "token": "WITHHASH",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "store",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "STORE",
+ "name": "storekey",
+ "display": "key",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "token": "STOREDIST",
+ "name": "storedistkey",
+ "display": "key",
+ "type": "key",
+ "key_spec_index": 2
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "Array of matched members information",
+ "anyOf": [
+ {
+ "description": "If no WITH* option is specified, array of matched members names",
+ "type": "array",
+ "items": {
+ "description": "name",
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Matched member name",
+ "type": "string"
+ }
+ ],
+ "additionalItems": {
+ "oneOf": [
+ {
+ "description": "If WITHDIST option is specified, the distance from the center as a floating point number, in the same unit specified in the radius",
+ "type": "string"
+ },
+ {
+ "description": "If WITHHASH option is specified, the geohash integer",
+ "type": "integer"
+ },
+ {
+ "description": "If WITHCOORD option is specified, the coordinates as a two items x,y array (longitude,latitude)",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "description": "number of items stored in key",
+ "type": "integer"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/georadius_ro.json b/src/commands/georadius_ro.json
new file mode 100644
index 0000000..964246a
--- /dev/null
+++ b/src/commands/georadius_ro.json
@@ -0,0 +1,201 @@
+{
+ "GEORADIUS_RO": {
+ "summary": "Returns members from a geospatial index that are within a distance from a coordinate.",
+ "complexity": "O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.",
+ "group": "geo",
+ "since": "3.2.10",
+ "arity": -6,
+ "function": "georadiusroCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `ANY` option for `COUNT`."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`GEOSEARCH` with the `BYRADIUS` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "longitude",
+ "type": "double"
+ },
+ {
+ "name": "latitude",
+ "type": "double"
+ },
+ {
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ },
+ {
+ "name": "withcoord",
+ "token": "WITHCOORD",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withdist",
+ "token": "WITHDIST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withhash",
+ "token": "WITHHASH",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "Array of matched members information",
+ "anyOf": [
+ {
+ "description": "If no WITH* option is specified, array of matched members names",
+ "type": "array",
+ "items": {
+ "description": "name",
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Matched member name",
+ "type": "string"
+ }
+ ],
+ "additionalItems": {
+ "oneOf": [
+ {
+ "description": "If WITHDIST option is specified, the distance from the center as a floating point number, in the same unit specified in the radius",
+ "type": "string"
+ },
+ {
+ "description": "If WITHHASH option is specified, the geohash integer",
+ "type": "integer"
+ },
+ {
+ "description": "If WITHCOORD option is specified, the coordinates as a two items x,y array (longitude,latitude)",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/georadiusbymember.json b/src/commands/georadiusbymember.json
new file mode 100644
index 0000000..4b62741
--- /dev/null
+++ b/src/commands/georadiusbymember.json
@@ -0,0 +1,261 @@
+{
+ "GEORADIUSBYMEMBER": {
+ "summary": "Queries a geospatial index for members within a distance from a member, optionally stores the result.",
+ "complexity": "O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.",
+ "group": "geo",
+ "since": "3.2.0",
+ "arity": -5,
+ "function": "georadiusbymemberCommand",
+ "get_keys_function": "georadiusGetKeys",
+ "history": [
+ [
+ "7.0.0",
+ "Added support for uppercase unit names."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`GEOSEARCH` and `GEOSEARCHSTORE` with the `BYRADIUS` and `FROMMEMBER` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STORE",
+ "startfrom": 5
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STOREDIST",
+ "startfrom": 5
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ },
+ {
+ "name": "withcoord",
+ "token": "WITHCOORD",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withdist",
+ "token": "WITHDIST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withhash",
+ "token": "WITHHASH",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "store",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "STORE",
+ "name": "storekey",
+ "display": "key",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "token": "STOREDIST",
+ "name": "storedistkey",
+ "display": "key",
+ "type": "key",
+ "key_spec_index": 2
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "Array of matched members information",
+ "anyOf": [
+ {
+ "description": "If no WITH* option is specified, array of matched members names",
+ "type": "array",
+ "items": {
+ "description": "name",
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Matched member name",
+ "type": "string"
+ }
+ ],
+ "additionalItems": {
+ "oneOf": [
+ {
+ "description": "If WITHDIST option is specified, the distance from the center as a floating point number, in the same unit specified in the radius",
+ "type": "string"
+ },
+ {
+ "description": "If WITHHASH option is specified, the geohash integer",
+ "type": "integer"
+ },
+ {
+ "description": "If WITHCOORD option is specified, the coordinates as a two items x,y array (longitude,latitude)",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "description": "number of items stored in key",
+ "type": "integer"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/georadiusbymember_ro.json b/src/commands/georadiusbymember_ro.json
new file mode 100644
index 0000000..5925881
--- /dev/null
+++ b/src/commands/georadiusbymember_ro.json
@@ -0,0 +1,190 @@
+{
+ "GEORADIUSBYMEMBER_RO": {
+ "summary": "Returns members from a geospatial index that are within a distance from a member.",
+ "complexity": "O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.",
+ "group": "geo",
+ "since": "3.2.10",
+ "arity": -5,
+ "function": "georadiusbymemberroCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`GEOSEARCH` with the `BYRADIUS` and `FROMMEMBER` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ },
+ {
+ "name": "withcoord",
+ "token": "WITHCOORD",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withdist",
+ "token": "WITHDIST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withhash",
+ "token": "WITHHASH",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "Array of matched members information",
+ "anyOf": [
+ {
+ "description": "If no WITH* option is specified, array of matched members names",
+ "type": "array",
+ "items": {
+ "description": "name",
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Matched member name",
+ "type": "string"
+ }
+ ],
+ "additionalItems": {
+ "oneOf": [
+ {
+ "description": "If WITHDIST option is specified, the distance from the center as a floating point number, in the same unit specified in the radius",
+ "type": "string"
+ },
+ {
+ "description": "If WITHHASH option is specified, the geohash integer",
+ "type": "integer"
+ },
+ {
+ "description": "If WITHCOORD option is specified, the coordinates as a two items x,y array (longitude,latitude)",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/geosearch.json b/src/commands/geosearch.json
new file mode 100644
index 0000000..b2e2825
--- /dev/null
+++ b/src/commands/geosearch.json
@@ -0,0 +1,267 @@
+{
+ "GEOSEARCH": {
+ "summary": "Queries a geospatial index for members inside an area of a box or a circle.",
+ "complexity": "O(N+log(M)) where N is the number of elements in the grid-aligned bounding box area around the shape provided as the filter and M is the number of items inside the shape",
+ "group": "geo",
+ "since": "6.2.0",
+ "arity": -7,
+ "function": "geosearchCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added support for uppercase unit names."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "from",
+ "type": "oneof",
+ "arguments": [
+ {
+ "token": "FROMMEMBER",
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "token": "FROMLONLAT",
+ "name": "fromlonlat",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "longitude",
+ "type": "double"
+ },
+ {
+ "name": "latitude",
+ "type": "double"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "by",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "circle",
+ "type": "block",
+ "arguments": [
+ {
+ "token": "BYRADIUS",
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "box",
+ "type": "block",
+ "arguments": [
+ {
+ "token": "BYBOX",
+ "name": "width",
+ "type": "double"
+ },
+ {
+ "name": "height",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "withcoord",
+ "token": "WITHCOORD",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withdist",
+ "token": "WITHDIST",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "withhash",
+ "token": "WITHHASH",
+ "type": "pure-token",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Array of matched members information",
+ "anyOf": [
+ {
+ "description": "If no WITH* option is specified, array of matched members names",
+ "type": "array",
+ "items": {
+ "description": "name",
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Matched member name",
+ "type": "string"
+ }
+ ],
+ "additionalItems": {
+ "oneOf": [
+ {
+ "description": "If WITHDIST option is specified, the distance from the center as a floating point number, in the same unit specified in the radius",
+ "type": "string"
+ },
+ {
+ "description": "If WITHHASH option is specified, the geohash integer",
+ "type": "integer"
+ },
+ {
+ "description": "If WITHCOORD option is specified, the coordinates as a two items x,y array (longitude,latitude)",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "latitude (x)",
+ "type": "number"
+ },
+ {
+ "description": "longitude (y)",
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/geosearchstore.json b/src/commands/geosearchstore.json
new file mode 100644
index 0000000..dfbdaaa
--- /dev/null
+++ b/src/commands/geosearchstore.json
@@ -0,0 +1,228 @@
+{
+ "GEOSEARCHSTORE": {
+ "summary": "Queries a geospatial index for members inside an area of a box or a circle, optionally stores the result.",
+ "complexity": "O(N+log(M)) where N is the number of elements in the grid-aligned bounding box area around the shape provided as the filter and M is the number of items inside the shape",
+ "group": "geo",
+ "since": "6.2.0",
+ "arity": -8,
+ "function": "geosearchstoreCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added support for uppercase unit names."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "GEO"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "from",
+ "type": "oneof",
+ "arguments": [
+ {
+ "token": "FROMMEMBER",
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "token": "FROMLONLAT",
+ "name": "fromlonlat",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "longitude",
+ "type": "double"
+ },
+ {
+ "name": "latitude",
+ "type": "double"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "by",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "circle",
+ "type": "block",
+ "arguments": [
+ {
+ "token": "BYRADIUS",
+ "name": "radius",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "box",
+ "type": "block",
+ "arguments": [
+ {
+ "token": "BYBOX",
+ "name": "width",
+ "type": "double"
+ },
+ {
+ "name": "height",
+ "type": "double"
+ },
+ {
+ "name": "unit",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "m",
+ "type": "pure-token",
+ "token": "m"
+ },
+ {
+ "name": "km",
+ "type": "pure-token",
+ "token": "km"
+ },
+ {
+ "name": "ft",
+ "type": "pure-token",
+ "token": "ft"
+ },
+ {
+ "name": "mi",
+ "type": "pure-token",
+ "token": "mi"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "count-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "any",
+ "token": "ANY",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "storedist",
+ "token": "STOREDIST",
+ "type": "pure-token",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of elements in the resulting set",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/get.json b/src/commands/get.json
new file mode 100644
index 0000000..693c1ac
--- /dev/null
+++ b/src/commands/get.json
@@ -0,0 +1,56 @@
+{
+ "GET": {
+ "summary": "Returns the string value of a key.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "getCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The value of the key.",
+ "type": "string"
+ },
+ {
+ "description": "Key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/getbit.json b/src/commands/getbit.json
new file mode 100644
index 0000000..629f5db
--- /dev/null
+++ b/src/commands/getbit.json
@@ -0,0 +1,59 @@
+{
+ "GETBIT": {
+ "summary": "Returns a bit value by offset.",
+ "complexity": "O(1)",
+ "group": "bitmap",
+ "since": "2.2.0",
+ "arity": 3,
+ "function": "getbitCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The bit value stored at offset.",
+ "oneOf": [
+ {
+ "const": 0
+ },
+ {
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/getdel.json b/src/commands/getdel.json
new file mode 100644
index 0000000..f3d86b0
--- /dev/null
+++ b/src/commands/getdel.json
@@ -0,0 +1,57 @@
+{
+ "GETDEL": {
+ "summary": "Returns the string value of a key after deleting the key.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "6.2.0",
+ "arity": 2,
+ "function": "getdelCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The value of the key.",
+ "type": "string"
+ },
+ {
+ "description": "The key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/getex.json b/src/commands/getex.json
new file mode 100644
index 0000000..978b9d1
--- /dev/null
+++ b/src/commands/getex.json
@@ -0,0 +1,90 @@
+{
+ "GETEX": {
+ "summary": "Returns the string value of a key after setting its expiration time.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "6.2.0",
+ "arity": -2,
+ "function": "getexCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "notes": "RW and UPDATE because it changes the TTL",
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The value of the key.",
+ "type": "string"
+ },
+ {
+ "description": "Key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "expiration",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "seconds",
+ "type": "integer",
+ "token": "EX"
+ },
+ {
+ "name": "milliseconds",
+ "type": "integer",
+ "token": "PX"
+ },
+ {
+ "name": "unix-time-seconds",
+ "type": "unix-time",
+ "token": "EXAT"
+ },
+ {
+ "name": "unix-time-milliseconds",
+ "type": "unix-time",
+ "token": "PXAT"
+ },
+ {
+ "name": "persist",
+ "type": "pure-token",
+ "token": "PERSIST"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/getrange.json b/src/commands/getrange.json
new file mode 100644
index 0000000..82bb723
--- /dev/null
+++ b/src/commands/getrange.json
@@ -0,0 +1,55 @@
+{
+ "GETRANGE": {
+ "summary": "Returns a substring of the string stored at a key.",
+ "complexity": "O(N) where N is the length of the returned string. The complexity is ultimately determined by the returned length, but because creating a substring from an existing string is very cheap, it can be considered O(1) for small strings.",
+ "group": "string",
+ "since": "2.4.0",
+ "arity": 4,
+ "function": "getrangeCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The substring of the string value stored at key, determined by the offsets start and end (both are inclusive)."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "end",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/getset.json b/src/commands/getset.json
new file mode 100644
index 0000000..42823d5
--- /dev/null
+++ b/src/commands/getset.json
@@ -0,0 +1,67 @@
+{
+ "GETSET": {
+ "summary": "Returns the previous string value of a key after setting it to a new value.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "getsetCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`SET` with the `!GET` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The old value stored at the key.",
+ "type": "string"
+ },
+ {
+ "description": "The key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hdel.json b/src/commands/hdel.json
new file mode 100644
index 0000000..11da02d
--- /dev/null
+++ b/src/commands/hdel.json
@@ -0,0 +1,59 @@
+{
+ "HDEL": {
+ "summary": "Deletes one or more fields and their values from a hash. Deletes the hash if no fields remain.",
+ "complexity": "O(N) where N is the number of fields to be removed.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "hdelCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple `field` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of fields that were removed from the hash."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/hello.json b/src/commands/hello.json
new file mode 100644
index 0000000..e916e72
--- /dev/null
+++ b/src/commands/hello.json
@@ -0,0 +1,111 @@
+{
+ "HELLO": {
+ "summary": "Handshakes with the Redis server.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.0.0",
+ "arity": -1,
+ "function": "helloCommand",
+ "history": [
+ [
+ "6.2.0",
+ "`protover` made optional; when called without arguments the command reports the current connection's context."
+ ]
+ ],
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "NO_AUTH",
+ "SENTINEL",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "server": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "proto": {
+ "const": 3
+ },
+ "id": {
+ "type": "integer"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string"
+ },
+ "modules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "ver": {
+ "type": "integer"
+ },
+ "path": {
+ "type": "string"
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "arguments",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "protover",
+ "type": "integer"
+ },
+ {
+ "token": "AUTH",
+ "name": "auth",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string"
+ },
+ {
+ "name": "password",
+ "type": "string"
+ }
+ ]
+ },
+ {
+ "token": "SETNAME",
+ "name": "clientname",
+ "type": "string",
+ "optional": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/hexists.json b/src/commands/hexists.json
new file mode 100644
index 0000000..f5ea405
--- /dev/null
+++ b/src/commands/hexists.json
@@ -0,0 +1,59 @@
+{
+ "HEXISTS": {
+ "summary": "Determines whether a field exists in a hash.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 3,
+ "function": "hexistsCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The hash does not contain the field, or key does not exist.",
+ "const": 0
+ },
+ {
+ "description": "The hash contains the field.",
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hget.json b/src/commands/hget.json
new file mode 100644
index 0000000..a041143
--- /dev/null
+++ b/src/commands/hget.json
@@ -0,0 +1,60 @@
+{
+ "HGET": {
+ "summary": "Returns the value of a field in a hash.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 3,
+ "function": "hgetCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The value associated with the field.",
+ "type": "string"
+ },
+ {
+ "description": "If the field is not present in the hash or key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hgetall.json b/src/commands/hgetall.json
new file mode 100644
index 0000000..9bbf835
--- /dev/null
+++ b/src/commands/hgetall.json
@@ -0,0 +1,53 @@
+{
+ "HGETALL": {
+ "summary": "Returns all fields and values in a hash.",
+ "complexity": "O(N) where N is the size of the hash.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 2,
+ "function": "hgetallCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "object",
+ "description": "Map of fields and their values stored in the hash, or an empty list when key does not exist. In RESP2 this is returned as a flat array.",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/hincrby.json b/src/commands/hincrby.json
new file mode 100644
index 0000000..a90f5ba
--- /dev/null
+++ b/src/commands/hincrby.json
@@ -0,0 +1,58 @@
+{
+ "HINCRBY": {
+ "summary": "Increments the integer value of a field in a hash by a number. Uses 0 as initial value if the field doesn't exist.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 4,
+ "function": "hincrbyCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The value of the field after the increment operation."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "increment",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hincrbyfloat.json b/src/commands/hincrbyfloat.json
new file mode 100644
index 0000000..6a7d1fd
--- /dev/null
+++ b/src/commands/hincrbyfloat.json
@@ -0,0 +1,58 @@
+{
+ "HINCRBYFLOAT": {
+ "summary": "Increments the floating point value of a field by a number. Uses 0 as initial value if the field doesn't exist.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.6.0",
+ "arity": 4,
+ "function": "hincrbyfloatCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The value of the field after the increment operation."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "increment",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hkeys.json b/src/commands/hkeys.json
new file mode 100644
index 0000000..917df1c
--- /dev/null
+++ b/src/commands/hkeys.json
@@ -0,0 +1,54 @@
+{
+ "HKEYS": {
+ "summary": "Returns all fields in a hash.",
+ "complexity": "O(N) where N is the size of the hash.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 2,
+ "function": "hkeysCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of fields in the hash, or an empty list when the key does not exist.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/hlen.json b/src/commands/hlen.json
new file mode 100644
index 0000000..d4c13ac
--- /dev/null
+++ b/src/commands/hlen.json
@@ -0,0 +1,47 @@
+{
+ "HLEN": {
+ "summary": "Returns the number of fields in a hash.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 2,
+ "function": "hlenCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of the fields in the hash, or 0 when the key does not exist."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/hmget.json b/src/commands/hmget.json
new file mode 100644
index 0000000..73fa9c3
--- /dev/null
+++ b/src/commands/hmget.json
@@ -0,0 +1,64 @@
+{
+ "HMGET": {
+ "summary": "Returns the values of all fields in a hash.",
+ "complexity": "O(N) where N is the number of fields being requested.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "hmgetCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "List of values associated with the given fields, in the same order as they are requested.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/hmset.json b/src/commands/hmset.json
new file mode 100644
index 0000000..e92f411
--- /dev/null
+++ b/src/commands/hmset.json
@@ -0,0 +1,68 @@
+{
+ "HMSET": {
+ "summary": "Sets the values of multiple fields.",
+ "complexity": "O(N) where N is the number of fields being set.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": -4,
+ "function": "hsetCommand",
+ "deprecated_since": "4.0.0",
+ "replaced_by": "`HSET` with multiple field-value pairs",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/hrandfield.json b/src/commands/hrandfield.json
new file mode 100644
index 0000000..83abc74
--- /dev/null
+++ b/src/commands/hrandfield.json
@@ -0,0 +1,101 @@
+{
+ "HRANDFIELD": {
+ "summary": "Returns one or more random fields from a hash.",
+ "complexity": "O(N) where N is the number of fields returned",
+ "group": "hash",
+ "since": "6.2.0",
+ "arity": -2,
+ "function": "hrandfieldCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "Key doesn't exist",
+ "type": "null"
+ },
+ {
+ "description": "A single random field. Returned in case `COUNT` was not used.",
+ "type": "string"
+ },
+ {
+ "description": "A list of fields. Returned in case `COUNT` was used.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "Fields and their values. Returned in case `COUNT` and `WITHVALUES` were used. In RESP2 this is returned as a flat array.",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Field",
+ "type": "string"
+ },
+ {
+ "description": "Value",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "options",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "withvalues",
+ "token": "WITHVALUES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/hscan.json b/src/commands/hscan.json
new file mode 100644
index 0000000..0888eec
--- /dev/null
+++ b/src/commands/hscan.json
@@ -0,0 +1,81 @@
+{
+ "HSCAN": {
+ "summary": "Iterates over fields and values of a hash.",
+ "complexity": "O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.",
+ "group": "hash",
+ "since": "2.8.0",
+ "arity": -3,
+ "function": "hscanCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "cursor",
+ "type": "integer"
+ },
+ {
+ "token": "MATCH",
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "cursor and scan response in array form",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "cursor",
+ "type": "string"
+ },
+ {
+ "description": "list of key/value pairs from the hash where each even element is the key, and each odd element is the value",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/hset.json b/src/commands/hset.json
new file mode 100644
index 0000000..8180972
--- /dev/null
+++ b/src/commands/hset.json
@@ -0,0 +1,70 @@
+{
+ "HSET": {
+ "summary": "Creates or modifies the value of a field in a hash.",
+ "complexity": "O(1) for each field/value pair added, so O(N) to add N field/value pairs when the command is called with multiple field/value pairs.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": -4,
+ "function": "hsetCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Accepts multiple `field` and `value` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of fields that were added",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/hsetnx.json b/src/commands/hsetnx.json
new file mode 100644
index 0000000..e024c41
--- /dev/null
+++ b/src/commands/hsetnx.json
@@ -0,0 +1,65 @@
+{
+ "HSETNX": {
+ "summary": "Sets the value of a field in a hash only when the field doesn't exist.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 4,
+ "function": "hsetnxCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The field is a new field in the hash and value was set.",
+ "const": 0
+ },
+ {
+ "description": "The field already exists in the hash and no operation was performed.",
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hstrlen.json b/src/commands/hstrlen.json
new file mode 100644
index 0000000..82ac6db
--- /dev/null
+++ b/src/commands/hstrlen.json
@@ -0,0 +1,52 @@
+{
+ "HSTRLEN": {
+ "summary": "Returns the length of the value of a field.",
+ "complexity": "O(1)",
+ "group": "hash",
+ "since": "3.2.0",
+ "arity": 3,
+ "function": "hstrlenCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "String length of the value associated with the field, or zero when the field is not present in the hash or key does not exist at all.",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "field",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/hvals.json b/src/commands/hvals.json
new file mode 100644
index 0000000..55aeaaf
--- /dev/null
+++ b/src/commands/hvals.json
@@ -0,0 +1,53 @@
+{
+ "HVALS": {
+ "summary": "Returns all values in a hash.",
+ "complexity": "O(N) where N is the size of the hash.",
+ "group": "hash",
+ "since": "2.0.0",
+ "arity": 2,
+ "function": "hvalsCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "HASH"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of values in the hash, or an empty list when the key does not exist.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/incr.json b/src/commands/incr.json
new file mode 100644
index 0000000..f33ec02
--- /dev/null
+++ b/src/commands/incr.json
@@ -0,0 +1,50 @@
+{
+ "INCR": {
+ "summary": "Increments the integer value of a key by one. Uses 0 as initial value if the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "incrCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "description": "The value of key after the increment",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/incrby.json b/src/commands/incrby.json
new file mode 100644
index 0000000..2668011
--- /dev/null
+++ b/src/commands/incrby.json
@@ -0,0 +1,54 @@
+{
+ "INCRBY": {
+ "summary": "Increments the integer value of a key by a number. Uses 0 as initial value if the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "incrbyCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The value of the key after incrementing it."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "increment",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/incrbyfloat.json b/src/commands/incrbyfloat.json
new file mode 100644
index 0000000..c594a1a
--- /dev/null
+++ b/src/commands/incrbyfloat.json
@@ -0,0 +1,54 @@
+{
+ "INCRBYFLOAT": {
+ "summary": "Increment the floating point value of a key by a number. Uses 0 as initial value if the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "2.6.0",
+ "arity": 3,
+ "function": "incrbyfloatCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The value of the key after incrementing it."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "increment",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/info.json b/src/commands/info.json
new file mode 100644
index 0000000..04a02b1
--- /dev/null
+++ b/src/commands/info.json
@@ -0,0 +1,41 @@
+{
+ "INFO": {
+ "summary": "Returns information and statistics about the server.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "infoCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added support for taking multiple section arguments."
+ ]
+ ],
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "DANGEROUS"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "description": "A map of info fields, one field per line in the form of <field>:<value> where the value can be a comma separated map like <key>=<val>. Also contains section header lines starting with `#` and blank lines.",
+ "type": "string"
+ },
+ "arguments": [
+ {
+ "name": "section",
+ "type": "string",
+ "multiple": true,
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/keys.json b/src/commands/keys.json
new file mode 100644
index 0000000..9dd4e11
--- /dev/null
+++ b/src/commands/keys.json
@@ -0,0 +1,34 @@
+{
+ "KEYS": {
+ "summary": "Returns all key names that match a pattern.",
+ "complexity": "O(N) with N being the number of keys in the database, under the assumption that the key names in the database and the given pattern have limited length.",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "keysCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern"
+ }
+ ],
+ "reply_schema": {
+ "description": "list of keys matching pattern",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/lastsave.json b/src/commands/lastsave.json
new file mode 100644
index 0000000..dc06154
--- /dev/null
+++ b/src/commands/lastsave.json
@@ -0,0 +1,26 @@
+{
+ "LASTSAVE": {
+ "summary": "Returns the Unix timestamp of the last successful save to disk.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "lastsaveCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "FAST"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "acl_categories": [
+ "ADMIN",
+ "DANGEROUS"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "UNIX TIME of the last DB save executed with success."
+ }
+ }
+}
diff --git a/src/commands/latency-doctor.json b/src/commands/latency-doctor.json
new file mode 100644
index 0000000..8f1f8dd
--- /dev/null
+++ b/src/commands/latency-doctor.json
@@ -0,0 +1,26 @@
+{
+ "DOCTOR": {
+ "summary": "Returns a human-readable latency analysis report.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 2,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "A human readable latency analysis report."
+ }
+ }
+}
diff --git a/src/commands/latency-graph.json b/src/commands/latency-graph.json
new file mode 100644
index 0000000..cb5d209
--- /dev/null
+++ b/src/commands/latency-graph.json
@@ -0,0 +1,32 @@
+{
+ "GRAPH": {
+ "summary": "Returns a latency graph for an event.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 3,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "arguments": [
+ {
+ "name": "event",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "Latency graph"
+ }
+ }
+}
diff --git a/src/commands/latency-help.json b/src/commands/latency-help.json
new file mode 100644
index 0000000..36ff527
--- /dev/null
+++ b/src/commands/latency-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 2,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/latency-histogram.json b/src/commands/latency-histogram.json
new file mode 100644
index 0000000..5e33eb6
--- /dev/null
+++ b/src/commands/latency-histogram.json
@@ -0,0 +1,54 @@
+{
+ "HISTOGRAM": {
+ "summary": "Returns the cumulative distribution of latencies of a subset or all commands.",
+ "complexity": "O(N) where N is the number of commands with latency information being retrieved.",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "description": "A map where each key is a command name, and each value is a map with the total calls, and an inner map of the histogram time buckets.",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "calls": {
+ "description": "The total calls for the command.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "histogram_usec": {
+ "description": "Histogram map, bucket id to latency",
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "COMMAND",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/latency-history.json b/src/commands/latency-history.json
new file mode 100644
index 0000000..7c3591a
--- /dev/null
+++ b/src/commands/latency-history.json
@@ -0,0 +1,49 @@
+{
+ "HISTORY": {
+ "summary": "Returns timestamp-latency samples for an event.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 3,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "An array where each element is a two elements array representing the timestamp and the latency of the event.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "timestamp of the event",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "latency of the event",
+ "type": "integer",
+ "minimum": 0
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "event",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/latency-latest.json b/src/commands/latency-latest.json
new file mode 100644
index 0000000..88c9e7a
--- /dev/null
+++ b/src/commands/latency-latest.json
@@ -0,0 +1,49 @@
+{
+ "LATEST": {
+ "summary": "Returns the latest latency samples for all events.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": 2,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "An array where each element is a four elements array representing the event's name, timestamp, latest and all-time latency measurements.",
+ "items": {
+ "type": "array",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "type": "string",
+ "description": "Event name."
+ },
+ {
+ "type": "integer",
+ "description": "Timestamp."
+ },
+ {
+ "type": "integer",
+ "description": "Latest latency in milliseconds."
+ },
+ {
+ "type": "integer",
+ "description": "Max latency in milliseconds."
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/latency-reset.json b/src/commands/latency-reset.json
new file mode 100644
index 0000000..3223282
--- /dev/null
+++ b/src/commands/latency-reset.json
@@ -0,0 +1,33 @@
+{
+ "RESET": {
+ "summary": "Resets the latency data for one or more events.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": -2,
+ "container": "LATENCY",
+ "function": "latencyCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of event time series that were reset."
+ },
+ "arguments": [
+ {
+ "name": "event",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/latency.json b/src/commands/latency.json
new file mode 100644
index 0000000..e4844d4
--- /dev/null
+++ b/src/commands/latency.json
@@ -0,0 +1,9 @@
+{
+ "LATENCY": {
+ "summary": "A container for latency diagnostics commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "2.8.13",
+ "arity": -2
+ }
+}
diff --git a/src/commands/lcs.json b/src/commands/lcs.json
new file mode 100644
index 0000000..a26b089
--- /dev/null
+++ b/src/commands/lcs.json
@@ -0,0 +1,127 @@
+{
+ "LCS": {
+ "summary": "Finds the longest common substring.",
+ "complexity": "O(N*M) where N and M are the lengths of s1 and s2, respectively",
+ "group": "string",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "lcsCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The longest common subsequence."
+ },
+ {
+ "type": "integer",
+ "description": "The length of the longest common subsequence when 'LEN' is given."
+ },
+ {
+ "type": "object",
+ "description": "Array with the LCS length and all the ranges in both the strings when 'IDX' is given. In RESP2 this is returned as a flat array",
+ "additionalProperties": false,
+ "properties": {
+ "matches": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 3,
+ "items": [
+ {
+ "type": "array",
+ "description": "Matched range in the first string.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": {
+ "type": "integer"
+ }
+ },
+ {
+ "type": "array",
+ "description": "Matched range in the second string.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": {
+ "type": "integer"
+ }
+ }
+ ],
+ "additionalItems": {
+ "type": "integer",
+ "description": "The length of the match when 'WITHMATCHLEN' is given."
+ }
+ }
+ },
+ "len": {
+ "type": "integer",
+ "description": "Length of the longest common subsequence."
+ }
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key1",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "key2",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "len",
+ "token": "LEN",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "idx",
+ "token": "IDX",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "MINMATCHLEN",
+ "name": "min-match-len",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "withmatchlen",
+ "token": "WITHMATCHLEN",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lindex.json b/src/commands/lindex.json
new file mode 100644
index 0000000..a589d52
--- /dev/null
+++ b/src/commands/lindex.json
@@ -0,0 +1,59 @@
+{
+ "LINDEX": {
+ "summary": "Returns an element from a list by its index.",
+ "complexity": "O(N) where N is the number of elements to traverse to get to the element at index. This makes asking for the first or the last element of the list O(1).",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "lindexCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "Index is out of range"
+ },
+ {
+ "description": "The requested element",
+ "type": "string"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "index",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/linsert.json b/src/commands/linsert.json
new file mode 100644
index 0000000..8059dc5
--- /dev/null
+++ b/src/commands/linsert.json
@@ -0,0 +1,85 @@
+{
+ "LINSERT": {
+ "summary": "Inserts an element before or after another element in a list.",
+ "complexity": "O(N) where N is the number of elements to traverse before seeing the value pivot. This means that inserting somewhere on the left end on the list (head) can be considered O(1) and inserting somewhere on the right end (tail) is O(N).",
+ "group": "list",
+ "since": "2.2.0",
+ "arity": 5,
+ "function": "linsertCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "List length after a successful insert operation.",
+ "type": "integer",
+ "minimum": 1
+ },
+ {
+ "description": "in case key doesn't exist.",
+ "const": 0
+ },
+ {
+ "description": "when the pivot wasn't found.",
+ "const": -1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "where",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "before",
+ "type": "pure-token",
+ "token": "BEFORE"
+ },
+ {
+ "name": "after",
+ "type": "pure-token",
+ "token": "AFTER"
+ }
+ ]
+ },
+ {
+ "name": "pivot",
+ "type": "string"
+ },
+ {
+ "name": "element",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/llen.json b/src/commands/llen.json
new file mode 100644
index 0000000..846aa40
--- /dev/null
+++ b/src/commands/llen.json
@@ -0,0 +1,48 @@
+{
+ "LLEN": {
+ "summary": "Returns the length of a list.",
+ "complexity": "O(1)",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "llenCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "List length.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/lmove.json b/src/commands/lmove.json
new file mode 100644
index 0000000..ab0c6ad
--- /dev/null
+++ b/src/commands/lmove.json
@@ -0,0 +1,104 @@
+{
+ "LMOVE": {
+ "summary": "Returns an element after popping it from one list and pushing it to another. Deletes the list if the last element was moved.",
+ "complexity": "O(1)",
+ "group": "list",
+ "since": "6.2.0",
+ "arity": 5,
+ "function": "lmoveCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The element being popped and pushed.",
+ "type": "string"
+ },
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "wherefrom",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ },
+ {
+ "name": "whereto",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/lmpop.json b/src/commands/lmpop.json
new file mode 100644
index 0000000..7cc3476
--- /dev/null
+++ b/src/commands/lmpop.json
@@ -0,0 +1,100 @@
+{
+ "LMPOP": {
+ "summary": "Returns multiple elements from a list after removing them. Deletes the list if the last element was popped.",
+ "complexity": "O(N+M) where N is the number of provided keys and M is the number of elements returned.",
+ "group": "list",
+ "since": "7.0.0",
+ "arity": -4,
+ "function": "lmpopCommand",
+ "get_keys_function": "lmpopGetKeys",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "If no element could be popped.",
+ "type": "null"
+ },
+ {
+ "description": "List key from which elements were popped.",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Name of the key from which elements were popped.",
+ "type": "string"
+ },
+ {
+ "description": "Array of popped elements.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "where",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "left",
+ "type": "pure-token",
+ "token": "LEFT"
+ },
+ {
+ "name": "right",
+ "type": "pure-token",
+ "token": "RIGHT"
+ }
+ ]
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lolwut.json b/src/commands/lolwut.json
new file mode 100644
index 0000000..546c14c
--- /dev/null
+++ b/src/commands/lolwut.json
@@ -0,0 +1,25 @@
+{
+ "LOLWUT": {
+ "summary": "Displays computer art and the Redis version",
+ "group": "server",
+ "since": "5.0.0",
+ "arity": -1,
+ "function": "lolwutCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "String containing the generative computer art, and a text with the Redis version."
+ },
+ "arguments": [
+ {
+ "token": "VERSION",
+ "name": "version",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lpop.json b/src/commands/lpop.json
new file mode 100644
index 0000000..b1d6cd1
--- /dev/null
+++ b/src/commands/lpop.json
@@ -0,0 +1,77 @@
+{
+ "LPOP": {
+ "summary": "Returns the first elements in a list after removing it. Deletes the list if the last element was popped.",
+ "complexity": "O(N) where N is the number of elements returned",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "lpopCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `count` argument."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Key does not exist.",
+ "type": "null"
+ },
+ {
+ "description": "In case `count` argument was not given, the value of the first element.",
+ "type": "string"
+ },
+ {
+ "description": "In case `count` argument was given, a list of popped elements",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ }
+}
diff --git a/src/commands/lpos.json b/src/commands/lpos.json
new file mode 100644
index 0000000..7b63b72
--- /dev/null
+++ b/src/commands/lpos.json
@@ -0,0 +1,85 @@
+{
+ "LPOS": {
+ "summary": "Returns the index of matching elements in a list.",
+ "complexity": "O(N) where N is the number of elements in the list, for the average case. When searching for elements near the head or the tail of the list, or when the MAXLEN option is provided, the command may run in constant time.",
+ "group": "list",
+ "since": "6.0.6",
+ "arity": -3,
+ "function": "lposCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "In case there is no matching element",
+ "type": "null"
+ },
+ {
+ "description": "An integer representing the matching element",
+ "type": "integer"
+ },
+ {
+ "description": "If the COUNT option is given, an array of integers representing the matching elements (empty if there are no matches)",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "integer"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string"
+ },
+ {
+ "token": "RANK",
+ "name": "rank",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "COUNT",
+ "name": "num-matches",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "MAXLEN",
+ "name": "len",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lpush.json b/src/commands/lpush.json
new file mode 100644
index 0000000..34cd8e2
--- /dev/null
+++ b/src/commands/lpush.json
@@ -0,0 +1,60 @@
+{
+ "LPUSH": {
+ "summary": "Prepends one or more elements to a list. Creates the key if it doesn't exist.",
+ "complexity": "O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "lpushCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple `element` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Length of the list after the push operations.",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lpushx.json b/src/commands/lpushx.json
new file mode 100644
index 0000000..5f6d17c
--- /dev/null
+++ b/src/commands/lpushx.json
@@ -0,0 +1,61 @@
+{
+ "LPUSHX": {
+ "summary": "Prepends one or more elements to a list only when the list exists.",
+ "complexity": "O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.",
+ "group": "list",
+ "since": "2.2.0",
+ "arity": -3,
+ "function": "lpushxCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Accepts multiple `element` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "the length of the list after the push operation",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/lrange.json b/src/commands/lrange.json
new file mode 100644
index 0000000..303d2f6
--- /dev/null
+++ b/src/commands/lrange.json
@@ -0,0 +1,58 @@
+{
+ "LRANGE": {
+ "summary": "Returns a range of elements from a list.",
+ "complexity": "O(S+N) where S is the distance of start offset from HEAD for small lists, from nearest end (HEAD or TAIL) for large lists; and N is the number of elements in the specified range.",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "lrangeCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "stop",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "description": "List of elements in the specified range",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/lrem.json b/src/commands/lrem.json
new file mode 100644
index 0000000..c267d3e
--- /dev/null
+++ b/src/commands/lrem.json
@@ -0,0 +1,56 @@
+{
+ "LREM": {
+ "summary": "Removes elements from a list. Deletes the list if the last element was removed.",
+ "complexity": "O(N+M) where N is the length of the list and M is the number of elements removed.",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "lremCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of removed elements.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "element",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/lset.json b/src/commands/lset.json
new file mode 100644
index 0000000..473b02c
--- /dev/null
+++ b/src/commands/lset.json
@@ -0,0 +1,55 @@
+{
+ "LSET": {
+ "summary": "Sets the value of an element in a list by its index.",
+ "complexity": "O(N) where N is the length of the list. Setting either the first or the last element of the list is O(1).",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "lsetCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "index",
+ "type": "integer"
+ },
+ {
+ "name": "element",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/ltrim.json b/src/commands/ltrim.json
new file mode 100644
index 0000000..3bba299
--- /dev/null
+++ b/src/commands/ltrim.json
@@ -0,0 +1,54 @@
+{
+ "LTRIM": {
+ "summary": "Removes elements from both ends a list. Deletes the list if all elements were trimmed.",
+ "complexity": "O(N) where N is the number of elements to be removed by the operation.",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "ltrimCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "stop",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/memory-doctor.json b/src/commands/memory-doctor.json
new file mode 100644
index 0000000..c0c8c22
--- /dev/null
+++ b/src/commands/memory-doctor.json
@@ -0,0 +1,20 @@
+{
+ "DOCTOR": {
+ "summary": "Outputs a memory problems report.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "description": "memory problems report",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/memory-help.json b/src/commands/memory-help.json
new file mode 100644
index 0000000..e72934c
--- /dev/null
+++ b/src/commands/memory-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/memory-malloc-stats.json b/src/commands/memory-malloc-stats.json
new file mode 100644
index 0000000..5ef6a31
--- /dev/null
+++ b/src/commands/memory-malloc-stats.json
@@ -0,0 +1,20 @@
+{
+ "MALLOC-STATS": {
+ "summary": "Returns the allocator statistics.",
+ "complexity": "Depends on how much memory is allocated, could be slow",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The memory allocator's internal statistics report."
+ }
+ }
+}
diff --git a/src/commands/memory-purge.json b/src/commands/memory-purge.json
new file mode 100644
index 0000000..77ed61d
--- /dev/null
+++ b/src/commands/memory-purge.json
@@ -0,0 +1,18 @@
+{
+ "PURGE": {
+ "summary": "Asks the allocator to release memory.",
+ "complexity": "Depends on how much memory is allocated, could be slow",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/memory-stats.json b/src/commands/memory-stats.json
new file mode 100644
index 0000000..de82dc8
--- /dev/null
+++ b/src/commands/memory-stats.json
@@ -0,0 +1,121 @@
+{
+ "STATS": {
+ "summary": "Returns details about memory usage.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "reply_schema": {
+ "description": "memory usage details",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "peak.allocated": {
+ "type": "integer"
+ },
+ "total.allocated": {
+ "type": "integer"
+ },
+ "startup.allocated": {
+ "type": "integer"
+ },
+ "replication.backlog": {
+ "type": "integer"
+ },
+ "clients.slaves": {
+ "type": "integer"
+ },
+ "clients.normal": {
+ "type": "integer"
+ },
+ "cluster.links": {
+ "type": "integer"
+ },
+ "aof.buffer": {
+ "type": "integer"
+ },
+ "lua.caches": {
+ "type": "integer"
+ },
+ "functions.caches": {
+ "type": "integer"
+ },
+ "overhead.total": {
+ "type": "integer"
+ },
+ "keys.count": {
+ "type": "integer"
+ },
+ "keys.bytes-per-key": {
+ "type": "integer"
+ },
+ "dataset.bytes": {
+ "type": "integer"
+ },
+ "dataset.percentage": {
+ "type": "number"
+ },
+ "peak.percentage": {
+ "type": "number"
+ },
+ "allocator.allocated": {
+ "type": "integer"
+ },
+ "allocator.active": {
+ "type": "integer"
+ },
+ "allocator.resident": {
+ "type": "integer"
+ },
+ "allocator-fragmentation.ratio": {
+ "type": "number"
+ },
+ "allocator-fragmentation.bytes": {
+ "type": "integer"
+ },
+ "allocator-rss.ratio": {
+ "type": "number"
+ },
+ "allocator-rss.bytes": {
+ "type": "integer"
+ },
+ "rss-overhead.ratio": {
+ "type": "number"
+ },
+ "rss-overhead.bytes": {
+ "type": "integer"
+ },
+ "fragmentation": {
+ "type": "number"
+ },
+ "fragmentation.bytes": {
+ "type": "integer"
+ }
+ },
+ "patternProperties": {
+ "^db.": {
+ "type": "object",
+ "properties": {
+ "overhead.hashtable.main": {
+ "type": "integer"
+ },
+ "overhead.hashtable.expires": {
+ "type": "integer"
+ },
+ "overhead.hashtable.slot-to-keys": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/memory-usage.json b/src/commands/memory-usage.json
new file mode 100644
index 0000000..78678ad
--- /dev/null
+++ b/src/commands/memory-usage.json
@@ -0,0 +1,58 @@
+{
+ "USAGE": {
+ "summary": "Estimates the memory usage of a key.",
+ "complexity": "O(N) where N is the number of samples.",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": -3,
+ "container": "MEMORY",
+ "function": "memoryCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Number of bytes that a key and its value require to be stored in RAM.",
+ "type": "integer"
+ },
+ {
+ "description": "Key does not exist.",
+ "type": "null"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "token": "SAMPLES",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/memory.json b/src/commands/memory.json
new file mode 100644
index 0000000..aab0841
--- /dev/null
+++ b/src/commands/memory.json
@@ -0,0 +1,9 @@
+{
+ "MEMORY": {
+ "summary": "A container for memory diagnostics commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/mget.json b/src/commands/mget.json
new file mode 100644
index 0000000..a177853
--- /dev/null
+++ b/src/commands/mget.json
@@ -0,0 +1,63 @@
+{
+ "MGET": {
+ "summary": "Atomically returns the string values of one or more keys.",
+ "complexity": "O(N) where N is the number of keys to retrieve.",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "mgetCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "List of values at the specified keys.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/migrate.json b/src/commands/migrate.json
new file mode 100644
index 0000000..f1dfae4
--- /dev/null
+++ b/src/commands/migrate.json
@@ -0,0 +1,181 @@
+{
+ "MIGRATE": {
+ "summary": "Atomically transfers a key from one Redis instance to another.",
+ "complexity": "This command actually executes a DUMP+DEL in the source instance, and a RESTORE in the target instance. See the pages of these commands for time complexity. Also an O(N) data transfer between the two instances is performed.",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": -6,
+ "function": "migrateCommand",
+ "get_keys_function": "migrateGetKeys",
+ "history": [
+ [
+ "3.0.0",
+ "Added the `COPY` and `REPLACE` options."
+ ],
+ [
+ "3.0.6",
+ "Added the `KEYS` option."
+ ],
+ [
+ "4.0.7",
+ "Added the `AUTH` option."
+ ],
+ [
+ "6.0.0",
+ "Added the `AUTH2` option."
+ ]
+ ],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 3
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE",
+ "INCOMPLETE"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "KEYS",
+ "startfrom": -2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": "OK",
+ "description": "Success."
+ },
+ {
+ "const": "NOKEY",
+ "description": "No keys were found in the source instance."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "host",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ },
+ {
+ "name": "key-selector",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "empty-string",
+ "type": "pure-token",
+ "token": "\"\""
+ }
+ ]
+ },
+ {
+ "name": "destination-db",
+ "type": "integer"
+ },
+ {
+ "name": "timeout",
+ "type": "integer"
+ },
+ {
+ "name": "copy",
+ "token": "COPY",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.0"
+ },
+ {
+ "name": "replace",
+ "token": "REPLACE",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.0"
+ },
+ {
+ "name": "authentication",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "AUTH",
+ "name": "auth",
+ "display": "password",
+ "type": "string",
+ "since": "4.0.7"
+ },
+ {
+ "token": "AUTH2",
+ "name": "auth2",
+ "type": "block",
+ "since": "6.0.0",
+ "arguments": [
+ {
+ "name": "username",
+ "type": "string"
+ },
+ {
+ "name": "password",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "token": "KEYS",
+ "name": "keys",
+ "display": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "optional": true,
+ "multiple": true,
+ "since": "3.0.6"
+ }
+ ]
+ }
+}
diff --git a/src/commands/module-help.json b/src/commands/module-help.json
new file mode 100644
index 0000000..5f3db0f
--- /dev/null
+++ b/src/commands/module-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "MODULE",
+ "function": "moduleCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/module-list.json b/src/commands/module-list.json
new file mode 100644
index 0000000..92a022b
--- /dev/null
+++ b/src/commands/module-list.json
@@ -0,0 +1,47 @@
+{
+ "LIST": {
+ "summary": "Returns all loaded modules.",
+ "complexity": "O(N) where N is the number of loaded modules.",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 2,
+ "container": "MODULE",
+ "function": "moduleCommand",
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Returns information about the modules loaded to the server.",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the module."
+ },
+ "ver": {
+ "type": "integer",
+ "description": "Version of the module."
+ },
+ "path": {
+ "type": "string",
+ "description": "Module path."
+ },
+ "args": {
+ "type": "array",
+ "description": "Module arguments.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/module-load.json b/src/commands/module-load.json
new file mode 100644
index 0000000..dd5d654
--- /dev/null
+++ b/src/commands/module-load.json
@@ -0,0 +1,32 @@
+{
+ "LOAD": {
+ "summary": "Loads a module.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": -3,
+ "container": "MODULE",
+ "function": "moduleCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "PROTECTED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "path",
+ "type": "string"
+ },
+ {
+ "name": "arg",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/module-loadex.json b/src/commands/module-loadex.json
new file mode 100644
index 0000000..6c750ea
--- /dev/null
+++ b/src/commands/module-loadex.json
@@ -0,0 +1,51 @@
+{
+ "LOADEX": {
+ "summary": "Loads a module using extended parameters.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "7.0.0",
+ "arity": -3,
+ "container": "MODULE",
+ "function": "moduleCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "PROTECTED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "path",
+ "type": "string"
+ },
+ {
+ "name": "configs",
+ "token": "CONFIG",
+ "type": "block",
+ "multiple": true,
+ "multiple_token": true,
+ "optional": true,
+ "arguments": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ },
+ {
+ "name": "args",
+ "token": "ARGS",
+ "type": "string",
+ "multiple": true,
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/module-unload.json b/src/commands/module-unload.json
new file mode 100644
index 0000000..f2fbf80
--- /dev/null
+++ b/src/commands/module-unload.json
@@ -0,0 +1,26 @@
+{
+ "UNLOAD": {
+ "summary": "Unloads a module.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 3,
+ "container": "MODULE",
+ "function": "moduleCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "PROTECTED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/module.json b/src/commands/module.json
new file mode 100644
index 0000000..148f182
--- /dev/null
+++ b/src/commands/module.json
@@ -0,0 +1,9 @@
+{
+ "MODULE": {
+ "summary": "A container for module commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/monitor.json b/src/commands/monitor.json
new file mode 100644
index 0000000..23c659e
--- /dev/null
+++ b/src/commands/monitor.json
@@ -0,0 +1,16 @@
+{
+ "MONITOR": {
+ "summary": "Listens for all requests received by the server in real-time.",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "monitorCommand",
+ "history": [],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ]
+ }
+}
diff --git a/src/commands/move.json b/src/commands/move.json
new file mode 100644
index 0000000..2030680
--- /dev/null
+++ b/src/commands/move.json
@@ -0,0 +1,61 @@
+{
+ "MOVE": {
+ "summary": "Moves a key to another database.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "moveCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "db",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "key was moved",
+ "const": 1
+ },
+ {
+ "description": "key wasn't moved",
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/mset.json b/src/commands/mset.json
new file mode 100644
index 0000000..9a57446
--- /dev/null
+++ b/src/commands/mset.json
@@ -0,0 +1,62 @@
+{
+ "MSET": {
+ "summary": "Atomically creates or modifies the string values of one or more keys.",
+ "complexity": "O(N) where N is the number of keys to set.",
+ "group": "string",
+ "since": "1.0.1",
+ "arity": -3,
+ "function": "msetCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 2,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/msetnx.json b/src/commands/msetnx.json
new file mode 100644
index 0000000..27592d3
--- /dev/null
+++ b/src/commands/msetnx.json
@@ -0,0 +1,67 @@
+{
+ "MSETNX": {
+ "summary": "Atomically modifies the string values of one or more keys only when all keys don't exist.",
+ "complexity": "O(N) where N is the number of keys to set.",
+ "group": "string",
+ "since": "1.0.1",
+ "arity": -3,
+ "function": "msetnxCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 2,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "No key was set (at least one key already existed).",
+ "const": 0
+ },
+ {
+ "description": "All the keys were set.",
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/multi.json b/src/commands/multi.json
new file mode 100644
index 0000000..5f17a1d
--- /dev/null
+++ b/src/commands/multi.json
@@ -0,0 +1,23 @@
+{
+ "MULTI": {
+ "summary": "Starts a transaction.",
+ "complexity": "O(1)",
+ "group": "transactions",
+ "since": "1.2.0",
+ "arity": 1,
+ "function": "multiCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "TRANSACTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/object-encoding.json b/src/commands/object-encoding.json
new file mode 100644
index 0000000..f255b57
--- /dev/null
+++ b/src/commands/object-encoding.json
@@ -0,0 +1,58 @@
+{
+ "ENCODING": {
+ "summary": "Returns the internal encoding of a Redis object.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.2.3",
+ "arity": 3,
+ "container": "OBJECT",
+ "function": "objectCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "key doesn't exist",
+ "type": "null"
+ },
+ {
+ "description": "encoding of the object",
+ "type": "string"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/object-freq.json b/src/commands/object-freq.json
new file mode 100644
index 0000000..03b5b2b
--- /dev/null
+++ b/src/commands/object-freq.json
@@ -0,0 +1,50 @@
+{
+ "FREQ": {
+ "summary": "Returns the logarithmic access frequency counter of a Redis object.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "4.0.0",
+ "arity": 3,
+ "container": "OBJECT",
+ "function": "objectCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "description": "the counter's value",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/object-help.json b/src/commands/object-help.json
new file mode 100644
index 0000000..5261650
--- /dev/null
+++ b/src/commands/object-help.json
@@ -0,0 +1,25 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "OBJECT",
+ "function": "objectCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/object-idletime.json b/src/commands/object-idletime.json
new file mode 100644
index 0000000..03c202a
--- /dev/null
+++ b/src/commands/object-idletime.json
@@ -0,0 +1,50 @@
+{
+ "IDLETIME": {
+ "summary": "Returns the time since the last access to a Redis object.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.2.3",
+ "arity": 3,
+ "container": "OBJECT",
+ "function": "objectCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "description": "the idle time in seconds",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/object-refcount.json b/src/commands/object-refcount.json
new file mode 100644
index 0000000..48009bb
--- /dev/null
+++ b/src/commands/object-refcount.json
@@ -0,0 +1,50 @@
+{
+ "REFCOUNT": {
+ "summary": "Returns the reference count of a value of a key.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.2.3",
+ "arity": 3,
+ "container": "OBJECT",
+ "function": "objectCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of references",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/object.json b/src/commands/object.json
new file mode 100644
index 0000000..14be26b
--- /dev/null
+++ b/src/commands/object.json
@@ -0,0 +1,9 @@
+{
+ "OBJECT": {
+ "summary": "A container for object introspection commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "generic",
+ "since": "2.2.3",
+ "arity": -2
+ }
+}
diff --git a/src/commands/persist.json b/src/commands/persist.json
new file mode 100644
index 0000000..11e6e01
--- /dev/null
+++ b/src/commands/persist.json
@@ -0,0 +1,56 @@
+{
+ "PERSIST": {
+ "summary": "Removes the expiration time of a key.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.2.0",
+ "arity": 2,
+ "function": "persistCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "Key does not exist or does not have an associated timeout."
+ },
+ {
+ "const": 1,
+ "description": "The timeout has been removed."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/pexpire.json b/src/commands/pexpire.json
new file mode 100644
index 0000000..a133f4f
--- /dev/null
+++ b/src/commands/pexpire.json
@@ -0,0 +1,94 @@
+{
+ "PEXPIRE": {
+ "summary": "Sets the expiration time of a key in milliseconds.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": -3,
+ "function": "pexpireCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added options: `NX`, `XX`, `GT` and `LT`."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "The timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments."
+ },
+ {
+ "const": 1,
+ "description": "The timeout was set."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "milliseconds",
+ "type": "integer"
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ },
+ {
+ "name": "gt",
+ "type": "pure-token",
+ "token": "GT"
+ },
+ {
+ "name": "lt",
+ "type": "pure-token",
+ "token": "LT"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/pexpireat.json b/src/commands/pexpireat.json
new file mode 100644
index 0000000..dd08ed0
--- /dev/null
+++ b/src/commands/pexpireat.json
@@ -0,0 +1,94 @@
+{
+ "PEXPIREAT": {
+ "summary": "Sets the expiration time of a key to a Unix milliseconds timestamp.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": -3,
+ "function": "pexpireatCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added options: `NX`, `XX`, `GT` and `LT`."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 1,
+ "description": "The timeout was set."
+ },
+ {
+ "const": 0,
+ "description": "The timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "unix-time-milliseconds",
+ "type": "unix-time"
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "7.0.0",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ },
+ {
+ "name": "gt",
+ "type": "pure-token",
+ "token": "GT"
+ },
+ {
+ "name": "lt",
+ "type": "pure-token",
+ "token": "LT"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/pexpiretime.json b/src/commands/pexpiretime.json
new file mode 100644
index 0000000..3fa055c
--- /dev/null
+++ b/src/commands/pexpiretime.json
@@ -0,0 +1,61 @@
+{
+ "PEXPIRETIME": {
+ "summary": "Returns the expiration time of a key as a Unix milliseconds timestamp.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "7.0.0",
+ "arity": 2,
+ "function": "pexpiretimeCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "integer",
+ "description": "Expiration Unix timestamp in milliseconds.",
+ "minimum": 0
+ },
+ {
+ "const": -1,
+ "description": "The key exists but has no associated expiration time."
+ },
+ {
+ "const": -2,
+ "description": "The key does not exist."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/pfadd.json b/src/commands/pfadd.json
new file mode 100644
index 0000000..7d8448a
--- /dev/null
+++ b/src/commands/pfadd.json
@@ -0,0 +1,63 @@
+{
+ "PFADD": {
+ "summary": "Adds elements to a HyperLogLog key. Creates the key if it doesn't exist.",
+ "complexity": "O(1) to add every element.",
+ "group": "hyperloglog",
+ "since": "2.8.9",
+ "arity": -2,
+ "function": "pfaddCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "HYPERLOGLOG"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "if at least 1 HyperLogLog internal register was altered",
+ "const": 1
+ },
+ {
+ "description": "if no HyperLogLog internal register were altered",
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/pfcount.json b/src/commands/pfcount.json
new file mode 100644
index 0000000..02a64c3
--- /dev/null
+++ b/src/commands/pfcount.json
@@ -0,0 +1,50 @@
+{
+ "PFCOUNT": {
+ "summary": "Returns the approximated cardinality of the set(s) observed by the HyperLogLog key(s).",
+ "complexity": "O(1) with a very small average constant time when called with a single key. O(N) with N being the number of keys, and much bigger constant times, when called with multiple keys.",
+ "group": "hyperloglog",
+ "since": "2.8.9",
+ "arity": -2,
+ "function": "pfcountCommand",
+ "command_flags": [
+ "READONLY",
+ "MAY_REPLICATE"
+ ],
+ "acl_categories": [
+ "HYPERLOGLOG"
+ ],
+ "key_specs": [
+ {
+ "notes": "RW because it may change the internal representation of the key, and propagate to replicas",
+ "flags": [
+ "RW",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "The approximated number of unique elements observed via PFADD",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/commands/pfdebug.json b/src/commands/pfdebug.json
new file mode 100644
index 0000000..4cd2853
--- /dev/null
+++ b/src/commands/pfdebug.json
@@ -0,0 +1,52 @@
+{
+ "PFDEBUG": {
+ "summary": "Internal commands for debugging HyperLogLog values.",
+ "complexity": "N/A",
+ "group": "hyperloglog",
+ "since": "2.8.9",
+ "arity": 3,
+ "function": "pfdebugCommand",
+ "doc_flags": [
+ "SYSCMD"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "ADMIN"
+ ],
+ "acl_categories": [
+ "HYPERLOGLOG"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "subcommand",
+ "type": "string"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/pfmerge.json b/src/commands/pfmerge.json
new file mode 100644
index 0000000..c93070f
--- /dev/null
+++ b/src/commands/pfmerge.json
@@ -0,0 +1,73 @@
+{
+ "PFMERGE": {
+ "summary": "Merges one or more HyperLogLog values into a single key.",
+ "complexity": "O(N) to merge N HyperLogLogs, but with high constant times.",
+ "group": "hyperloglog",
+ "since": "2.8.9",
+ "arity": -2,
+ "function": "pfmergeCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "HYPERLOGLOG"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "destkey",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "sourcekey",
+ "type": "key",
+ "key_spec_index": 1,
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/pfselftest.json b/src/commands/pfselftest.json
new file mode 100644
index 0000000..ed29280
--- /dev/null
+++ b/src/commands/pfselftest.json
@@ -0,0 +1,22 @@
+{
+ "PFSELFTEST": {
+ "summary": "An internal command for testing HyperLogLog values.",
+ "complexity": "N/A",
+ "group": "hyperloglog",
+ "since": "2.8.9",
+ "arity": 1,
+ "function": "pfselftestCommand",
+ "doc_flags": [
+ "SYSCMD"
+ ],
+ "command_flags": [
+ "ADMIN"
+ ],
+ "acl_categories": [
+ "HYPERLOGLOG"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/ping.json b/src/commands/ping.json
new file mode 100644
index 0000000..b634c0b
--- /dev/null
+++ b/src/commands/ping.json
@@ -0,0 +1,40 @@
+{
+ "PING": {
+ "summary": "Returns the server's liveliness response.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "pingCommand",
+ "command_flags": [
+ "FAST",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "const": "PONG",
+ "description": "Default reply."
+ },
+ {
+ "type": "string",
+ "description": "Relay of given `message`."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "message",
+ "type": "string",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/psetex.json b/src/commands/psetex.json
new file mode 100644
index 0000000..8d88766
--- /dev/null
+++ b/src/commands/psetex.json
@@ -0,0 +1,60 @@
+{
+ "PSETEX": {
+ "summary": "Sets both string value and expiration time in milliseconds of a key. The key is created if it doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "2.6.0",
+ "arity": 4,
+ "function": "psetexCommand",
+ "deprecated_since": "2.6.12",
+ "replaced_by": "`SET` with the `PX` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "milliseconds",
+ "type": "integer"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/psubscribe.json b/src/commands/psubscribe.json
new file mode 100644
index 0000000..cab5d14
--- /dev/null
+++ b/src/commands/psubscribe.json
@@ -0,0 +1,24 @@
+{
+ "PSUBSCRIBE": {
+ "summary": "Listens for messages published to channels that match one or more patterns.",
+ "complexity": "O(N) where N is the number of patterns to subscribe to.",
+ "group": "pubsub",
+ "since": "2.0.0",
+ "arity": -2,
+ "function": "psubscribeCommand",
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/psync.json b/src/commands/psync.json
new file mode 100644
index 0000000..60da8ed
--- /dev/null
+++ b/src/commands/psync.json
@@ -0,0 +1,25 @@
+{
+ "PSYNC": {
+ "summary": "An internal command used in replication.",
+ "group": "server",
+ "since": "2.8.0",
+ "arity": -3,
+ "function": "syncCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NO_MULTI",
+ "NOSCRIPT"
+ ],
+ "arguments": [
+ {
+ "name": "replicationid",
+ "type": "string"
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/pttl.json b/src/commands/pttl.json
new file mode 100644
index 0000000..304270b
--- /dev/null
+++ b/src/commands/pttl.json
@@ -0,0 +1,70 @@
+{
+ "PTTL": {
+ "summary": "Returns the expiration time in milliseconds of a key.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": 2,
+ "function": "pttlCommand",
+ "history": [
+ [
+ "2.8.0",
+ "Added the -2 reply."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "TTL in milliseconds.",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "The key exists but has no associated expire.",
+ "const": -1
+ },
+ {
+ "description": "The key does not exist.",
+ "const": -2
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/publish.json b/src/commands/publish.json
new file mode 100644
index 0000000..1dd757d
--- /dev/null
+++ b/src/commands/publish.json
@@ -0,0 +1,33 @@
+{
+ "PUBLISH": {
+ "summary": "Posts a message to a channel.",
+ "complexity": "O(N+M) where N is the number of clients subscribed to the receiving channel and M is the total number of subscribed patterns (by any client).",
+ "group": "pubsub",
+ "since": "2.0.0",
+ "arity": 3,
+ "function": "publishCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "MAY_REPLICATE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "channel",
+ "type": "string"
+ },
+ {
+ "name": "message",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/pubsub-channels.json b/src/commands/pubsub-channels.json
new file mode 100644
index 0000000..08505b3
--- /dev/null
+++ b/src/commands/pubsub-channels.json
@@ -0,0 +1,31 @@
+{
+ "CHANNELS": {
+ "summary": "Returns the active channels.",
+ "complexity": "O(N) where N is the number of active channels, and assuming constant time pattern matching (relatively short channels and patterns)",
+ "group": "pubsub",
+ "since": "2.8.0",
+ "arity": -2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "a list of active channels, optionally matching the specified pattern",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/pubsub-help.json b/src/commands/pubsub-help.json
new file mode 100644
index 0000000..32faedc
--- /dev/null
+++ b/src/commands/pubsub-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "pubsub",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/pubsub-numpat.json b/src/commands/pubsub-numpat.json
new file mode 100644
index 0000000..ae653b7
--- /dev/null
+++ b/src/commands/pubsub-numpat.json
@@ -0,0 +1,21 @@
+{
+ "NUMPAT": {
+ "summary": "Returns a count of unique pattern subscriptions.",
+ "complexity": "O(1)",
+ "group": "pubsub",
+ "since": "2.8.0",
+ "arity": 2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "description": "the number of patterns all the clients are subscribed to",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/pubsub-numsub.json b/src/commands/pubsub-numsub.json
new file mode 100644
index 0000000..1cfe8e2
--- /dev/null
+++ b/src/commands/pubsub-numsub.json
@@ -0,0 +1,28 @@
+{
+ "NUMSUB": {
+ "summary": "Returns a count of subscribers to channels.",
+ "complexity": "O(N) for the NUMSUB subcommand, where N is the number of requested channels",
+ "group": "pubsub",
+ "since": "2.8.0",
+ "arity": -2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "channel",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of subscribers per channel, each even element (including 0th) is channel name, each odd element is the number of subscribers",
+ "type": "array"
+ }
+ }
+}
diff --git a/src/commands/pubsub-shardchannels.json b/src/commands/pubsub-shardchannels.json
new file mode 100644
index 0000000..7aa0a7a
--- /dev/null
+++ b/src/commands/pubsub-shardchannels.json
@@ -0,0 +1,31 @@
+{
+ "SHARDCHANNELS": {
+ "summary": "Returns the active shard channels.",
+ "complexity": "O(N) where N is the number of active shard channels, and assuming constant time pattern matching (relatively short shard channels).",
+ "group": "pubsub",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "a list of active channels, optionally matching the specified pattern",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ }
+ }
+}
diff --git a/src/commands/pubsub-shardnumsub.json b/src/commands/pubsub-shardnumsub.json
new file mode 100644
index 0000000..4367534
--- /dev/null
+++ b/src/commands/pubsub-shardnumsub.json
@@ -0,0 +1,28 @@
+{
+ "SHARDNUMSUB": {
+ "summary": "Returns the count of subscribers of shard channels.",
+ "complexity": "O(N) for the SHARDNUMSUB subcommand, where N is the number of requested shard channels",
+ "group": "pubsub",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "PUBSUB",
+ "function": "pubsubCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "shardchannel",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of subscribers per shard channel, each even element (including 0th) is channel name, each odd element is the number of subscribers",
+ "type": "array"
+ }
+ }
+}
diff --git a/src/commands/pubsub.json b/src/commands/pubsub.json
new file mode 100644
index 0000000..2f0bb5e
--- /dev/null
+++ b/src/commands/pubsub.json
@@ -0,0 +1,9 @@
+{
+ "PUBSUB": {
+ "summary": "A container for Pub/Sub commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "pubsub",
+ "since": "2.8.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/punsubscribe.json b/src/commands/punsubscribe.json
new file mode 100644
index 0000000..cb977d8
--- /dev/null
+++ b/src/commands/punsubscribe.json
@@ -0,0 +1,25 @@
+{
+ "PUNSUBSCRIBE": {
+ "summary": "Stops listening to messages published to channels that match one or more patterns.",
+ "complexity": "O(N) where N is the number of patterns to unsubscribe.",
+ "group": "pubsub",
+ "since": "2.0.0",
+ "arity": -1,
+ "function": "punsubscribeCommand",
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/quit.json b/src/commands/quit.json
new file mode 100644
index 0000000..e8dd6e9
--- /dev/null
+++ b/src/commands/quit.json
@@ -0,0 +1,29 @@
+{
+ "QUIT": {
+ "summary": "Closes the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "quitCommand",
+ "deprecated_since": "7.2.0",
+ "replaced_by": "just closing the connection",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "ALLOW_BUSY",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "NO_AUTH"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/randomkey.json b/src/commands/randomkey.json
new file mode 100644
index 0000000..eeef61a
--- /dev/null
+++ b/src/commands/randomkey.json
@@ -0,0 +1,34 @@
+{
+ "RANDOMKEY": {
+ "summary": "Returns a random key name from the database.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "randomkeyCommand",
+ "command_flags": [
+ "READONLY",
+ "TOUCHES_ARBITRARY_KEYS"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:SPECIAL",
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "when the database is empty",
+ "type": "null"
+ },
+ {
+ "description": "random key in db",
+ "type": "string"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/readonly.json b/src/commands/readonly.json
new file mode 100644
index 0000000..253573c
--- /dev/null
+++ b/src/commands/readonly.json
@@ -0,0 +1,21 @@
+{
+ "READONLY": {
+ "summary": "Enables read-only queries for a connection to a Redis Cluster replica node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 1,
+ "function": "readonlyCommand",
+ "command_flags": [
+ "FAST",
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/readwrite.json b/src/commands/readwrite.json
new file mode 100644
index 0000000..440dd59
--- /dev/null
+++ b/src/commands/readwrite.json
@@ -0,0 +1,21 @@
+{
+ "READWRITE": {
+ "summary": "Enables read-write queries for a connection to a Reids Cluster replica node.",
+ "complexity": "O(1)",
+ "group": "cluster",
+ "since": "3.0.0",
+ "arity": 1,
+ "function": "readwriteCommand",
+ "command_flags": [
+ "FAST",
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/rename.json b/src/commands/rename.json
new file mode 100644
index 0000000..a8b65ae
--- /dev/null
+++ b/src/commands/rename.json
@@ -0,0 +1,72 @@
+{
+ "RENAME": {
+ "summary": "Renames a key and overwrites the destination.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "renameCommand",
+ "history": [],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "newkey",
+ "type": "key",
+ "key_spec_index": 1
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/renamenx.json b/src/commands/renamenx.json
new file mode 100644
index 0000000..72f0569
--- /dev/null
+++ b/src/commands/renamenx.json
@@ -0,0 +1,86 @@
+{
+ "RENAMENX": {
+ "summary": "Renames a key only when the target key name doesn't exist.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "renamenxCommand",
+ "history": [
+ [
+ "3.2.0",
+ "The command no longer returns an error when source and destination names are the same."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "OW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "newkey",
+ "type": "key",
+ "key_spec_index": 1
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "key was renamed to newkey",
+ "const": 1
+ },
+ {
+ "description": "new key already exists",
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/replconf.json b/src/commands/replconf.json
new file mode 100644
index 0000000..e8efc7b
--- /dev/null
+++ b/src/commands/replconf.json
@@ -0,0 +1,23 @@
+{
+ "REPLCONF": {
+ "summary": "An internal command for configuring the replication stream.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "3.0.0",
+ "arity": -1,
+ "function": "replconfCommand",
+ "doc_flags": [
+ "SYSCMD"
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "ALLOW_BUSY"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/replicaof.json b/src/commands/replicaof.json
new file mode 100644
index 0000000..95e5cb4
--- /dev/null
+++ b/src/commands/replicaof.json
@@ -0,0 +1,59 @@
+{
+ "REPLICAOF": {
+ "summary": "Configures a server as replica of another, or promotes it to a master.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "5.0.0",
+ "arity": 3,
+ "function": "replicaofCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "args",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "host-port",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "host",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "no-one",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "no",
+ "type": "pure-token",
+ "token": "NO"
+ },
+ {
+ "name": "one",
+ "type": "pure-token",
+ "token": "ONE"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "replicaOf status",
+ "type": "string",
+ "pattern": "OK*"
+ }
+ }
+}
diff --git a/src/commands/reset.json b/src/commands/reset.json
new file mode 100644
index 0000000..3fb1a44
--- /dev/null
+++ b/src/commands/reset.json
@@ -0,0 +1,24 @@
+{
+ "RESET": {
+ "summary": "Resets the connection.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "6.2.0",
+ "arity": 1,
+ "function": "resetCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "NO_AUTH",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "RESET"
+ }
+ }
+}
diff --git a/src/commands/restore-asking.json b/src/commands/restore-asking.json
new file mode 100644
index 0000000..2694a87
--- /dev/null
+++ b/src/commands/restore-asking.json
@@ -0,0 +1,102 @@
+{
+ "RESTORE-ASKING": {
+ "summary": "An internal command for migrating keys in a cluster.",
+ "complexity": "O(1) to create the new key and additional O(N*M) to reconstruct the serialized value, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1). However for sorted set values the complexity is O(N*M*log(N)) because inserting values into sorted sets is O(log(N)).",
+ "group": "server",
+ "since": "3.0.0",
+ "arity": -4,
+ "function": "restoreCommand",
+ "history": [
+ [
+ "3.0.0",
+ "Added the `REPLACE` modifier."
+ ],
+ [
+ "5.0.0",
+ "Added the `ABSTTL` modifier."
+ ],
+ [
+ "5.0.0",
+ "Added the `IDLETIME` and `FREQ` options."
+ ]
+ ],
+ "doc_flags": [
+ "SYSCMD"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "ASKING"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "ttl",
+ "type": "integer"
+ },
+ {
+ "name": "serialized-value",
+ "type": "string"
+ },
+ {
+ "name": "replace",
+ "token": "REPLACE",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.0"
+ },
+ {
+ "name": "absttl",
+ "token": "ABSTTL",
+ "type": "pure-token",
+ "optional": true,
+ "since": "5.0.0"
+ },
+ {
+ "token": "IDLETIME",
+ "name": "seconds",
+ "type": "integer",
+ "optional": true,
+ "since": "5.0.0"
+ },
+ {
+ "token": "FREQ",
+ "name": "frequency",
+ "type": "integer",
+ "optional": true,
+ "since": "5.0.0"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/restore.json b/src/commands/restore.json
new file mode 100644
index 0000000..383dd45
--- /dev/null
+++ b/src/commands/restore.json
@@ -0,0 +1,98 @@
+{
+ "RESTORE": {
+ "summary": "Creates a key from the serialized representation of a value.",
+ "complexity": "O(1) to create the new key and additional O(N*M) to reconstruct the serialized value, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1). However for sorted set values the complexity is O(N*M*log(N)) because inserting values into sorted sets is O(log(N)).",
+ "group": "generic",
+ "since": "2.6.0",
+ "arity": -4,
+ "function": "restoreCommand",
+ "history": [
+ [
+ "3.0.0",
+ "Added the `REPLACE` modifier."
+ ],
+ [
+ "5.0.0",
+ "Added the `ABSTTL` modifier."
+ ],
+ [
+ "5.0.0",
+ "Added the `IDLETIME` and `FREQ` options."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "ttl",
+ "type": "integer"
+ },
+ {
+ "name": "serialized-value",
+ "type": "string"
+ },
+ {
+ "name": "replace",
+ "token": "REPLACE",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.0"
+ },
+ {
+ "name": "absttl",
+ "token": "ABSTTL",
+ "type": "pure-token",
+ "optional": true,
+ "since": "5.0.0"
+ },
+ {
+ "token": "IDLETIME",
+ "name": "seconds",
+ "type": "integer",
+ "optional": true,
+ "since": "5.0.0"
+ },
+ {
+ "token": "FREQ",
+ "name": "frequency",
+ "type": "integer",
+ "optional": true,
+ "since": "5.0.0"
+ }
+ ]
+ }
+}
diff --git a/src/commands/role.json b/src/commands/role.json
new file mode 100644
index 0000000..a0299fa
--- /dev/null
+++ b/src/commands/role.json
@@ -0,0 +1,134 @@
+{
+ "ROLE": {
+ "summary": "Returns the replication role.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.8.12",
+ "arity": 1,
+ "function": "roleCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "SENTINEL"
+ ],
+ "acl_categories": [
+ "ADMIN",
+ "DANGEROUS"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "const": "master"
+ },
+ {
+ "description": "current replication master offset",
+ "type": "integer"
+ },
+ {
+ "description": "connected replicas",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "replica ip",
+ "type": "string"
+ },
+ {
+ "description": "replica port",
+ "type": "string"
+ },
+ {
+ "description": "last acknowledged replication offset",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "array",
+ "minItems": 5,
+ "maxItems": 5,
+ "items": [
+ {
+ "const": "slave"
+ },
+ {
+ "description": "ip of master",
+ "type": "string"
+ },
+ {
+ "description": "port number of master",
+ "type": "integer"
+ },
+ {
+ "description": "state of the replication from the point of view of the master",
+ "oneOf": [
+ {
+ "description": "the instance is in handshake with its master",
+ "const": "handshake"
+ },
+ {
+ "description": "the instance in not active",
+ "const": "none"
+ },
+ {
+ "description": "the instance needs to connect to its master",
+ "const": "connect"
+ },
+ {
+ "description": "the master-replica connection is in progress",
+ "const": "connecting"
+ },
+ {
+ "description": "the master and replica are trying to perform the synchronization",
+ "const": "sync"
+ },
+ {
+ "description": "the replica is online",
+ "const": "connected"
+ },
+ {
+ "description": "instance state is unknown",
+ "const": "unknown"
+ }
+ ]
+ },
+ {
+ "description": "the amount of data received from the replica so far in terms of master replication offset",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "const": "sentinel"
+ },
+ {
+ "description": "list of master names monitored by this sentinel instance",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/rpop.json b/src/commands/rpop.json
new file mode 100644
index 0000000..79b5a92
--- /dev/null
+++ b/src/commands/rpop.json
@@ -0,0 +1,76 @@
+{
+ "RPOP": {
+ "summary": "Returns and removes the last elements of a list. Deletes the list if the last element was popped.",
+ "complexity": "O(N) where N is the number of elements returned",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "rpopCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `count` argument."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "Key does not exist."
+ },
+ {
+ "type": "string",
+ "description": "When 'COUNT' was not given, the value of the last element."
+ },
+ {
+ "type": "array",
+ "description": "When 'COUNT' was given, list of popped elements.",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ }
+}
diff --git a/src/commands/rpoplpush.json b/src/commands/rpoplpush.json
new file mode 100644
index 0000000..1951499
--- /dev/null
+++ b/src/commands/rpoplpush.json
@@ -0,0 +1,85 @@
+{
+ "RPOPLPUSH": {
+ "summary": "Returns the last element of a list after removing and pushing it to another list. Deletes the list if the last element was popped.",
+ "complexity": "O(1)",
+ "group": "list",
+ "since": "1.2.0",
+ "arity": 3,
+ "function": "rpoplpushCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`LMOVE` with the `RIGHT` and `LEFT` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The element being popped and pushed."
+ },
+ {
+ "type": "null",
+ "description": "Source list is empty."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ }
+ ]
+ }
+}
diff --git a/src/commands/rpush.json b/src/commands/rpush.json
new file mode 100644
index 0000000..e5d6908
--- /dev/null
+++ b/src/commands/rpush.json
@@ -0,0 +1,61 @@
+{
+ "RPUSH": {
+ "summary": "Appends one or more elements to a list. Creates the key if it doesn't exist.",
+ "complexity": "O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.",
+ "group": "list",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "rpushCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple `element` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Length of the list after the push operations.",
+ "type": "integer",
+ "minimum": 1
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/rpushx.json b/src/commands/rpushx.json
new file mode 100644
index 0000000..b41f9c5
--- /dev/null
+++ b/src/commands/rpushx.json
@@ -0,0 +1,61 @@
+{
+ "RPUSHX": {
+ "summary": "Appends an element to a list only when the list exists.",
+ "complexity": "O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.",
+ "group": "list",
+ "since": "2.2.0",
+ "arity": -3,
+ "function": "rpushxCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Accepts multiple `element` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "LIST"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Length of the list after the push operation.",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "element",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sadd.json b/src/commands/sadd.json
new file mode 100644
index 0000000..00b3c26
--- /dev/null
+++ b/src/commands/sadd.json
@@ -0,0 +1,60 @@
+{
+ "SADD": {
+ "summary": "Adds one or more members to a set. Creates the key if it doesn't exist.",
+ "complexity": "O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "saddCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple `member` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of elements that were added to the set, not including all the elements already present in the set.",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/save.json b/src/commands/save.json
new file mode 100644
index 0000000..0645e27
--- /dev/null
+++ b/src/commands/save.json
@@ -0,0 +1,19 @@
+{
+ "SAVE": {
+ "summary": "Synchronously saves the database(s) to disk.",
+ "complexity": "O(N) where N is the total number of keys in all databases",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "saveCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "NO_MULTI"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/scan.json b/src/commands/scan.json
new file mode 100644
index 0000000..a7df78a
--- /dev/null
+++ b/src/commands/scan.json
@@ -0,0 +1,72 @@
+{
+ "SCAN": {
+ "summary": "Iterates over the key names in the database.",
+ "complexity": "O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.",
+ "group": "generic",
+ "since": "2.8.0",
+ "arity": -2,
+ "function": "scanCommand",
+ "history": [
+ [
+ "6.0.0",
+ "Added the `TYPE` subcommand."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "TOUCHES_ARBITRARY_KEYS"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT",
+ "REQUEST_POLICY:SPECIAL",
+ "RESPONSE_POLICY:SPECIAL"
+ ],
+ "arguments": [
+ {
+ "name": "cursor",
+ "type": "integer"
+ },
+ {
+ "token": "MATCH",
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "TYPE",
+ "name": "type",
+ "type": "string",
+ "optional": true,
+ "since": "6.0.0"
+ }
+ ],
+ "reply_schema": {
+ "description": "cursor and scan response in array form",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "cursor",
+ "type": "string"
+ },
+ {
+ "description": "list of keys",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/scard.json b/src/commands/scard.json
new file mode 100644
index 0000000..8df0a4f
--- /dev/null
+++ b/src/commands/scard.json
@@ -0,0 +1,48 @@
+{
+ "SCARD": {
+ "summary": "Returns the number of members in a set.",
+ "complexity": "O(1)",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "scardCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The cardinality (number of elements) of the set, or 0 if key does not exist.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/script-debug.json b/src/commands/script-debug.json
new file mode 100644
index 0000000..ebba38a
--- /dev/null
+++ b/src/commands/script-debug.json
@@ -0,0 +1,43 @@
+{
+ "DEBUG": {
+ "summary": "Sets the debug mode of server-side Lua scripts.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "3.2.0",
+ "arity": 3,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "arguments": [
+ {
+ "name": "mode",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "yes",
+ "type": "pure-token",
+ "token": "YES"
+ },
+ {
+ "name": "sync",
+ "type": "pure-token",
+ "token": "SYNC"
+ },
+ {
+ "name": "no",
+ "type": "pure-token",
+ "token": "NO"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/script-exists.json b/src/commands/script-exists.json
new file mode 100644
index 0000000..d8c47e4
--- /dev/null
+++ b/src/commands/script-exists.json
@@ -0,0 +1,44 @@
+{
+ "EXISTS": {
+ "summary": "Determines whether server-side Lua scripts exist in the script cache.",
+ "complexity": "O(N) with N being the number of scripts to check (so checking a single script is an O(1) operation).",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": -3,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:AGG_LOGICAL_AND"
+ ],
+ "arguments": [
+ {
+ "name": "sha1",
+ "type": "string",
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "An array of integers that correspond to the specified SHA1 digest arguments.",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "description": "sha1 hash exists in script cache",
+ "const": 1
+ },
+ {
+ "description": "sha1 hash does not exist in script cache",
+ "const": 0
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/script-flush.json b/src/commands/script-flush.json
new file mode 100644
index 0000000..7487dc5
--- /dev/null
+++ b/src/commands/script-flush.json
@@ -0,0 +1,50 @@
+{
+ "FLUSH": {
+ "summary": "Removes all server-side Lua scripts from the script cache.",
+ "complexity": "O(N) with N being the number of scripts in cache",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": -2,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `ASYNC` and `SYNC` flushing mode modifiers."
+ ]
+ ],
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "flush-type",
+ "type": "oneof",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "async",
+ "type": "pure-token",
+ "token": "ASYNC"
+ },
+ {
+ "name": "sync",
+ "type": "pure-token",
+ "token": "SYNC"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/script-help.json b/src/commands/script-help.json
new file mode 100644
index 0000000..c5ea5df
--- /dev/null
+++ b/src/commands/script-help.json
@@ -0,0 +1,25 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/script-kill.json b/src/commands/script-kill.json
new file mode 100644
index 0000000..fe72d31
--- /dev/null
+++ b/src/commands/script-kill.json
@@ -0,0 +1,25 @@
+{
+ "KILL": {
+ "summary": "Terminates a server-side Lua script during execution.",
+ "complexity": "O(1)",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": 2,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:ONE_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/script-load.json b/src/commands/script-load.json
new file mode 100644
index 0000000..37f80fd
--- /dev/null
+++ b/src/commands/script-load.json
@@ -0,0 +1,32 @@
+{
+ "LOAD": {
+ "summary": "Loads a server-side Lua script to the script cache.",
+ "complexity": "O(N) with N being the length in bytes of the script body.",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": 3,
+ "container": "SCRIPT",
+ "function": "scriptCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "STALE"
+ ],
+ "acl_categories": [
+ "SCRIPTING"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "arguments": [
+ {
+ "name": "script",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The SHA1 digest of the script added into the script cache",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/script.json b/src/commands/script.json
new file mode 100644
index 0000000..1d420c1
--- /dev/null
+++ b/src/commands/script.json
@@ -0,0 +1,9 @@
+{
+ "SCRIPT": {
+ "summary": "A container for Lua scripts management commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "scripting",
+ "since": "2.6.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/sdiff.json b/src/commands/sdiff.json
new file mode 100644
index 0000000..ac04d03
--- /dev/null
+++ b/src/commands/sdiff.json
@@ -0,0 +1,55 @@
+{
+ "SDIFF": {
+ "summary": "Returns the difference of multiple sets.",
+ "complexity": "O(N) where N is the total number of elements in all given sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "sdiffCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List with the members of the resulting set.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sdiffstore.json b/src/commands/sdiffstore.json
new file mode 100644
index 0000000..94b2d24
--- /dev/null
+++ b/src/commands/sdiffstore.json
@@ -0,0 +1,73 @@
+{
+ "SDIFFSTORE": {
+ "summary": "Stores the difference of multiple sets in a key.",
+ "complexity": "O(N) where N is the total number of elements in all given sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "sdiffstoreCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of the elements in the resulting set.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/select.json b/src/commands/select.json
new file mode 100644
index 0000000..5cf8634
--- /dev/null
+++ b/src/commands/select.json
@@ -0,0 +1,27 @@
+{
+ "SELECT": {
+ "summary": "Changes the selected database.",
+ "complexity": "O(1)",
+ "group": "connection",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "selectCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "index",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-ckquorum.json b/src/commands/sentinel-ckquorum.json
new file mode 100644
index 0000000..cdd6cd1
--- /dev/null
+++ b/src/commands/sentinel-ckquorum.json
@@ -0,0 +1,26 @@
+{
+ "CKQUORUM": {
+ "summary": "Checks for a Redis Sentinel quorum.",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "Returns OK if the current Sentinel configuration is able to reach the quorum needed to failover a master, and the majority needed to authorize the failover.",
+ "pattern": "OK"
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-config.json b/src/commands/sentinel-config.json
new file mode 100644
index 0000000..a406125
--- /dev/null
+++ b/src/commands/sentinel-config.json
@@ -0,0 +1,121 @@
+{
+ "CONFIG": {
+ "summary": "Configures Redis Sentinel.",
+ "complexity": "O(N) when N is the number of configuration parameters provided",
+ "group": "sentinel",
+ "since": "6.2.0",
+ "arity": -4,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "history": [
+ [
+ "7.2.0",
+ "Added the ability to set and get multiple parameters in one call."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "object",
+ "description": "When 'SENTINEL-CONFIG GET' is called, returns a map.",
+ "properties": {
+ "resolve-hostnames": {
+ "oneOf": [
+ {
+ "const": "yes"
+ },
+ {
+ "const": "no"
+ }
+ ]
+ },
+ "announce-hostnames": {
+ "oneOf": [
+ {
+ "const": "yes"
+ },
+ {
+ "const": "no"
+ }
+ ]
+ },
+ "announce-ip": {
+ "type": "string"
+ },
+ "announce-port": {
+ "type": "string"
+ },
+ "sentinel-user": {
+ "type": "string"
+ },
+ "sentinel-pass": {
+ "type": "string"
+ },
+ "loglevel": {
+ "oneOf": [
+ {
+ "const": "debug"
+ },
+ {
+ "const": "verbose"
+ },
+ {
+ "const": "notice"
+ },
+ {
+ "const": "warning"
+ },
+ {
+ "const": "nothing"
+ },
+ {
+ "const": "unknown"
+ }
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "const": "OK",
+ "description": "When 'SENTINEL-CONFIG SET' is called, returns OK on success."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name":"action",
+ "type":"oneof",
+ "arguments":[
+ {
+ "name":"set",
+ "token":"SET",
+ "type":"block",
+ "multiple": true,
+ "arguments":[
+ {
+ "name":"parameter",
+ "type":"string"
+ },
+ {
+ "name":"value",
+ "type":"string"
+ }
+ ]
+ },
+ {
+ "token":"GET",
+ "name":"parameter",
+ "type":"string",
+ "multiple": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-debug.json b/src/commands/sentinel-debug.json
new file mode 100644
index 0000000..c671ec5
--- /dev/null
+++ b/src/commands/sentinel-debug.json
@@ -0,0 +1,49 @@
+{
+ "DEBUG": {
+ "summary": "Lists or updates the current configurable parameters of Redis Sentinel.",
+ "complexity": "O(N) where N is the number of configurable parameters",
+ "group": "sentinel",
+ "since": "7.0.0",
+ "arity": -2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The configuration update was successful.",
+ "const": "OK"
+ },
+ {
+ "description": "List of configurable time parameters and their values (milliseconds).",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "data",
+ "type": "block",
+ "optional": true,
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "parameter",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-failover.json b/src/commands/sentinel-failover.json
new file mode 100644
index 0000000..8f50375
--- /dev/null
+++ b/src/commands/sentinel-failover.json
@@ -0,0 +1,25 @@
+{
+ "FAILOVER": {
+ "summary": "Forces a Redis Sentinel failover.",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK",
+ "description": "Force a fail over as if the master was not reachable, and without asking for agreement to other Sentinels."
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-flushconfig.json b/src/commands/sentinel-flushconfig.json
new file mode 100644
index 0000000..b2fa5de
--- /dev/null
+++ b/src/commands/sentinel-flushconfig.json
@@ -0,0 +1,20 @@
+{
+ "FLUSHCONFIG": {
+ "summary": "Rewrites the Redis Sentinel configuration file.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK",
+ "description": "Force Sentinel to rewrite its configuration on disk, including the current Sentinel state."
+ }
+ }
+}
diff --git a/src/commands/sentinel-get-master-addr-by-name.json b/src/commands/sentinel-get-master-addr-by-name.json
new file mode 100644
index 0000000..998f95e
--- /dev/null
+++ b/src/commands/sentinel-get-master-addr-by-name.json
@@ -0,0 +1,38 @@
+{
+ "GET-MASTER-ADDR-BY-NAME": {
+ "summary": "Returns the port and address of a master Redis instance.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "IP addr or hostname."
+ },
+ {
+ "type": "string",
+ "description": "Port.",
+ "pattern": "[0-9]+"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-help.json b/src/commands/sentinel-help.json
new file mode 100644
index 0000000..d601450
--- /dev/null
+++ b/src/commands/sentinel-help.json
@@ -0,0 +1,24 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/sentinel-info-cache.json b/src/commands/sentinel-info-cache.json
new file mode 100644
index 0000000..af89f18
--- /dev/null
+++ b/src/commands/sentinel-info-cache.json
@@ -0,0 +1,64 @@
+{
+ "INFO-CACHE": {
+ "summary": "Returns the cached `INFO` replies from the deployment's instances.",
+ "complexity": "O(N) where N is the number of instances",
+ "group": "sentinel",
+ "since": "3.2.0",
+ "arity": -3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "This is actually a map, the odd entries are a master name, and the even entries are the last cached INFO output from that master and all its replicas.",
+ "minItems": 0,
+ "maxItems": 4294967295,
+ "items": [
+ {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The master name."
+ },
+ {
+ "type": "array",
+ "description": "This is an array of pairs, the odd entries are the INFO age, and the even entries are the cached INFO string. The first pair belong to the master and the rest are its replicas.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "The number of milliseconds since when the INFO was cached.",
+ "type": "integer"
+ },
+ {
+ "description": "The cached INFO string or null.",
+ "oneOf": [
+ {
+ "description": "The cached INFO string.",
+ "type": "string"
+ },
+ {
+ "description": "No cached INFO string.",
+ "type": "null"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "nodename",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-is-master-down-by-addr.json b/src/commands/sentinel-is-master-down-by-addr.json
new file mode 100644
index 0000000..a13e96b
--- /dev/null
+++ b/src/commands/sentinel-is-master-down-by-addr.json
@@ -0,0 +1,61 @@
+{
+ "IS-MASTER-DOWN-BY-ADDR": {
+ "summary": "Determines whether a master Redis instance is down.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 6,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "Master is up."
+ },
+ {
+ "const": 1,
+ "description": "Master is down."
+ }
+ ]
+ },
+ {
+ "type": "string",
+ "description": "Sentinel address."
+ },
+ {
+ "type": "integer",
+ "description": "Port."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "ip",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ },
+ {
+ "name": "current-epoch",
+ "type": "integer"
+ },
+ {
+ "name": "runid",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-master.json b/src/commands/sentinel-master.json
new file mode 100644
index 0000000..8ca446d
--- /dev/null
+++ b/src/commands/sentinel-master.json
@@ -0,0 +1,29 @@
+{
+ "MASTER": {
+ "summary": "Returns the state of a master Redis instance.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "object",
+ "description": "The state and info of the specified master.",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-masters.json b/src/commands/sentinel-masters.json
new file mode 100644
index 0000000..1e96b71
--- /dev/null
+++ b/src/commands/sentinel-masters.json
@@ -0,0 +1,26 @@
+{
+ "MASTERS": {
+ "summary": "Returns a list of monitored Redis masters.",
+ "complexity": "O(N) where N is the number of masters",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of monitored Redis masters, and their state.",
+ "items": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/sentinel-monitor.json b/src/commands/sentinel-monitor.json
new file mode 100644
index 0000000..cf6b4ee
--- /dev/null
+++ b/src/commands/sentinel-monitor.json
@@ -0,0 +1,37 @@
+{
+ "MONITOR": {
+ "summary": "Starts monitoring.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 6,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "ip",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ },
+ {
+ "name": "quorum",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-myid.json b/src/commands/sentinel-myid.json
new file mode 100644
index 0000000..4d366eb
--- /dev/null
+++ b/src/commands/sentinel-myid.json
@@ -0,0 +1,20 @@
+{
+ "MYID": {
+ "summary": "Returns the Redis Sentinel instance ID.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "description": "Node ID of the sentinel instance.",
+ "type": "string"
+ }
+ }
+}
diff --git a/src/commands/sentinel-pending-scripts.json b/src/commands/sentinel-pending-scripts.json
new file mode 100644
index 0000000..22dae47
--- /dev/null
+++ b/src/commands/sentinel-pending-scripts.json
@@ -0,0 +1,52 @@
+{
+ "PENDING-SCRIPTS": {
+ "summary": "Returns information about pending scripts for Redis Sentinel.",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 2,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of pending scripts.",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "argv": {
+ "type": "array",
+ "description": "Script arguments.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "flags": {
+ "type": "string",
+ "description": "Script flags."
+ },
+ "pid": {
+ "type": "string",
+ "description": "Script pid."
+ },
+ "run-time": {
+ "type": "string",
+ "description": "Script run-time."
+ },
+ "run-delay": {
+ "type": "string",
+ "description": "Script run-delay."
+ },
+ "retry-num": {
+ "type": "string",
+ "description": "Number of times we tried to execute the script."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/sentinel-remove.json b/src/commands/sentinel-remove.json
new file mode 100644
index 0000000..1fe084f
--- /dev/null
+++ b/src/commands/sentinel-remove.json
@@ -0,0 +1,25 @@
+{
+ "REMOVE": {
+ "summary": "Stops monitoring.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-replicas.json b/src/commands/sentinel-replicas.json
new file mode 100644
index 0000000..09d88f2
--- /dev/null
+++ b/src/commands/sentinel-replicas.json
@@ -0,0 +1,32 @@
+{
+ "REPLICAS": {
+ "summary": "Returns a list of the monitored Redis replicas.",
+ "complexity": "O(N) where N is the number of replicas",
+ "group": "sentinel",
+ "since": "5.0.0",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of replicas for this master, and their state.",
+ "items": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-reset.json b/src/commands/sentinel-reset.json
new file mode 100644
index 0000000..17b53a4
--- /dev/null
+++ b/src/commands/sentinel-reset.json
@@ -0,0 +1,26 @@
+{
+ "RESET": {
+ "summary": "Resets Redis masters by name matching a pattern.",
+ "complexity": "O(N) where N is the number of monitored masters",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of masters that were reset."
+ },
+ "arguments": [
+ {
+ "name": "pattern",
+ "type": "pattern"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-sentinels.json b/src/commands/sentinel-sentinels.json
new file mode 100644
index 0000000..fdaa5cb
--- /dev/null
+++ b/src/commands/sentinel-sentinels.json
@@ -0,0 +1,32 @@
+{
+ "SENTINELS": {
+ "summary": "Returns a list of Sentinel instances.",
+ "complexity": "O(N) where N is the number of Sentinels",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of sentinel instances, and their state.",
+ "items": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-set.json b/src/commands/sentinel-set.json
new file mode 100644
index 0000000..3e86196
--- /dev/null
+++ b/src/commands/sentinel-set.json
@@ -0,0 +1,40 @@
+{
+ "SET": {
+ "summary": "Changes the configuration of a monitored Redis master.",
+ "complexity": "O(1)",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": -5,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "option",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-simulate-failure.json b/src/commands/sentinel-simulate-failure.json
new file mode 100644
index 0000000..5031d44
--- /dev/null
+++ b/src/commands/sentinel-simulate-failure.json
@@ -0,0 +1,52 @@
+{
+ "SIMULATE-FAILURE": {
+ "summary": "Simulates failover scenarios.",
+ "group": "sentinel",
+ "since": "3.2.0",
+ "arity": -3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The simulated flag was set.",
+ "const": "OK"
+ },
+ {
+ "description": "Supported simulates flags. Returned in case `HELP` was used.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "mode",
+ "type": "oneof",
+ "optional":true,
+ "multiple":true,
+ "arguments": [
+ {
+ "name": "crash-after-election",
+ "type": "pure-token"
+ },
+ {
+ "name": "crash-after-promotion",
+ "type": "pure-token"
+ },
+ {
+ "name": "help",
+ "type": "pure-token"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel-slaves.json b/src/commands/sentinel-slaves.json
new file mode 100644
index 0000000..c1fec41
--- /dev/null
+++ b/src/commands/sentinel-slaves.json
@@ -0,0 +1,37 @@
+{
+ "SLAVES": {
+ "summary": "Returns a list of the monitored replicas.",
+ "complexity": "O(N) where N is the number of replicas.",
+ "group": "sentinel",
+ "since": "2.8.0",
+ "arity": 3,
+ "container": "SENTINEL",
+ "function": "sentinelCommand",
+ "deprecated_since": "5.0.0",
+ "replaced_by": "`SENTINEL REPLICAS`",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of monitored replicas, and their state.",
+ "items": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "master-name",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sentinel.json b/src/commands/sentinel.json
new file mode 100644
index 0000000..c14d5a3
--- /dev/null
+++ b/src/commands/sentinel.json
@@ -0,0 +1,14 @@
+{
+ "SENTINEL": {
+ "summary": "A container for Redis Sentinel commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "sentinel",
+ "since": "2.8.4",
+ "arity": -2,
+ "command_flags": [
+ "ADMIN",
+ "SENTINEL",
+ "ONLY_SENTINEL"
+ ]
+ }
+}
diff --git a/src/commands/set.json b/src/commands/set.json
new file mode 100644
index 0000000..8236bc7
--- /dev/null
+++ b/src/commands/set.json
@@ -0,0 +1,152 @@
+{
+ "SET": {
+ "summary": "Sets the string value of a key, ignoring its type. The key is created if it doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "setCommand",
+ "get_keys_function": "setGetKeys",
+ "history": [
+ [
+ "2.6.12",
+ "Added the `EX`, `PX`, `NX` and `XX` options."
+ ],
+ [
+ "6.0.0",
+ "Added the `KEEPTTL` option."
+ ],
+ [
+ "6.2.0",
+ "Added the `GET`, `EXAT` and `PXAT` option."
+ ],
+ [
+ "7.0.0",
+ "Allowed the `NX` and `GET` options to be used together."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "notes": "RW and ACCESS due to the optional `GET` argument",
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE",
+ "VARIABLE_FLAGS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf":[
+ {
+ "description": "`GET` not given: Operation was aborted (conflict with one of the `XX`/`NX` options).",
+ "type": "null"
+ },
+ {
+ "description": "`GET` not given: The key was set.",
+ "const": "OK"
+ },
+ {
+ "description": "`GET` given: The key didn't exist before the `SET`",
+ "type": "null"
+ },
+ {
+ "description": "`GET` given: The previous value of the key",
+ "type": "string"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "2.6.12",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ }
+ ]
+ },
+ {
+ "name": "get",
+ "token": "GET",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "name": "expiration",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "seconds",
+ "type": "integer",
+ "token": "EX",
+ "since": "2.6.12"
+ },
+ {
+ "name": "milliseconds",
+ "type": "integer",
+ "token": "PX",
+ "since": "2.6.12"
+ },
+ {
+ "name": "unix-time-seconds",
+ "type": "unix-time",
+ "token": "EXAT",
+ "since": "6.2.0"
+ },
+ {
+ "name": "unix-time-milliseconds",
+ "type": "unix-time",
+ "token": "PXAT",
+ "since": "6.2.0"
+ },
+ {
+ "name": "keepttl",
+ "type": "pure-token",
+ "token": "KEEPTTL",
+ "since": "6.0.0"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/setbit.json b/src/commands/setbit.json
new file mode 100644
index 0000000..a1f6726
--- /dev/null
+++ b/src/commands/setbit.json
@@ -0,0 +1,64 @@
+{
+ "SETBIT": {
+ "summary": "Sets or clears the bit at offset of the string value. Creates the key if it doesn't exist.",
+ "complexity": "O(1)",
+ "group": "bitmap",
+ "since": "2.2.0",
+ "arity": 4,
+ "function": "setbitCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "BITMAP"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The original bit value stored at offset.",
+ "oneOf": [
+ {
+ "const": 0
+ },
+ {
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "value",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/setex.json b/src/commands/setex.json
new file mode 100644
index 0000000..1543a41
--- /dev/null
+++ b/src/commands/setex.json
@@ -0,0 +1,60 @@
+{
+ "SETEX": {
+ "summary": "Sets the string value and expiration time of a key. Creates the key if it doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "2.0.0",
+ "arity": 4,
+ "function": "setexCommand",
+ "deprecated_since": "2.6.12",
+ "replaced_by": "`SET` with the `EX` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "seconds",
+ "type": "integer"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/setnx.json b/src/commands/setnx.json
new file mode 100644
index 0000000..7459724
--- /dev/null
+++ b/src/commands/setnx.json
@@ -0,0 +1,66 @@
+{
+ "SETNX": {
+ "summary": "Set the string value of a key only when the key doesn't exist.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "setnxCommand",
+ "deprecated_since": "2.6.12",
+ "replaced_by": "`SET` with the `NX` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The key was set.",
+ "const": 0
+ },
+ {
+ "description": "The key was not set.",
+ "const": 1
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/setrange.json b/src/commands/setrange.json
new file mode 100644
index 0000000..32a8c52
--- /dev/null
+++ b/src/commands/setrange.json
@@ -0,0 +1,57 @@
+{
+ "SETRANGE": {
+ "summary": "Overwrites a part of a string value with another by an offset. Creates the key if it doesn't exist.",
+ "complexity": "O(1), not counting the time taken to copy the new string in place. Usually, this string is very small so the amortized complexity is O(1). Otherwise, complexity is O(M) with M being the length of the value argument.",
+ "group": "string",
+ "since": "2.2.0",
+ "arity": 4,
+ "function": "setrangeCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Length of the string after it was modified by the command.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/shutdown.json b/src/commands/shutdown.json
new file mode 100644
index 0000000..a9e45d4
--- /dev/null
+++ b/src/commands/shutdown.json
@@ -0,0 +1,69 @@
+{
+ "SHUTDOWN": {
+ "summary": "Synchronously saves the database(s) to disk and shuts down the Redis server.",
+ "complexity": "O(N) when saving, where N is the total number of keys in all databases when saving data, otherwise O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": -1,
+ "function": "shutdownCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `NOW`, `FORCE` and `ABORT` modifiers."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "NO_MULTI",
+ "SENTINEL",
+ "ALLOW_BUSY"
+ ],
+ "arguments": [
+ {
+ "name": "save-selector",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "nosave",
+ "type": "pure-token",
+ "token": "NOSAVE"
+ },
+ {
+ "name": "save",
+ "type": "pure-token",
+ "token": "SAVE"
+ }
+ ]
+ },
+ {
+ "name": "now",
+ "type": "pure-token",
+ "token": "NOW",
+ "optional": true,
+ "since": "7.0.0"
+ },
+ {
+ "name": "force",
+ "type": "pure-token",
+ "token": "FORCE",
+ "optional": true,
+ "since": "7.0.0"
+ },
+ {
+ "name": "abort",
+ "type": "pure-token",
+ "token": "ABORT",
+ "optional": true,
+ "since": "7.0.0"
+ }
+ ],
+ "reply_schema": {
+ "description": "OK if ABORT was specified and shutdown was aborted. On successful shutdown, nothing is returned since the server quits and the connection is closed. On failure, an error is returned.",
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/sinter.json b/src/commands/sinter.json
new file mode 100644
index 0000000..ad5ac91
--- /dev/null
+++ b/src/commands/sinter.json
@@ -0,0 +1,55 @@
+{
+ "SINTER": {
+ "summary": "Returns the intersect of multiple sets.",
+ "complexity": "O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "sinterCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List with the members of the resulting set.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sintercard.json b/src/commands/sintercard.json
new file mode 100644
index 0000000..9a79183
--- /dev/null
+++ b/src/commands/sintercard.json
@@ -0,0 +1,60 @@
+{
+ "SINTERCARD": {
+ "summary": "Returns the number of members of the intersect of multiple sets.",
+ "complexity": "O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.",
+ "group": "set",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "sinterCardCommand",
+ "get_keys_function": "sintercardGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of the elements in the resulting intersection.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sinterstore.json b/src/commands/sinterstore.json
new file mode 100644
index 0000000..28ccfff
--- /dev/null
+++ b/src/commands/sinterstore.json
@@ -0,0 +1,73 @@
+{
+ "SINTERSTORE": {
+ "summary": "Stores the intersect of multiple sets in a key.",
+ "complexity": "O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "sinterstoreCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of the elements in the result set.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sismember.json b/src/commands/sismember.json
new file mode 100644
index 0000000..51ef920
--- /dev/null
+++ b/src/commands/sismember.json
@@ -0,0 +1,59 @@
+{
+ "SISMEMBER": {
+ "summary": "Determines whether a member belongs to a set.",
+ "complexity": "O(1)",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "sismemberCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "The element is not a member of the set, or the key does not exist."
+ },
+ {
+ "const": 1,
+ "description": "The element is a member of the set."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/slaveof.json b/src/commands/slaveof.json
new file mode 100644
index 0000000..6595960
--- /dev/null
+++ b/src/commands/slaveof.json
@@ -0,0 +1,64 @@
+{
+ "SLAVEOF": {
+ "summary": "Sets a Redis server as a replica of another, or promotes it to being a master.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 3,
+ "function": "replicaofCommand",
+ "deprecated_since": "5.0.0",
+ "replaced_by": "`REPLICAOF`",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NOSCRIPT",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "args",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "host-port",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "host",
+ "type": "string"
+ },
+ {
+ "name": "port",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "no-one",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "no",
+ "type": "pure-token",
+ "token": "NO"
+ },
+ {
+ "name": "one",
+ "type": "pure-token",
+ "token": "ONE"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "slaveOf status",
+ "type": "string",
+ "pattern": "OK*"
+ }
+ }
+}
diff --git a/src/commands/slowlog-get.json b/src/commands/slowlog-get.json
new file mode 100644
index 0000000..ffc54b5
--- /dev/null
+++ b/src/commands/slowlog-get.json
@@ -0,0 +1,74 @@
+{
+ "GET": {
+ "summary": "Returns the slow log's entries.",
+ "complexity": "O(N) where N is the number of entries returned",
+ "group": "server",
+ "since": "2.2.12",
+ "arity": -2,
+ "container": "SLOWLOG",
+ "function": "slowlogCommand",
+ "history": [
+ [
+ "4.0.0",
+ "Added client IP address, port and name to the reply."
+ ]
+ ],
+ "command_flags": [
+ "ADMIN",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Entries from the slow log in chronological order.",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 6,
+ "maxItems": 6,
+ "items": [
+ {
+ "type": "integer",
+ "description": "Slow log entry ID."
+ },
+ {
+ "type": "integer",
+ "description": "The unix timestamp at which the logged command was processed.",
+ "minimum": 0
+ },
+ {
+ "type": "integer",
+ "description": "The amount of time needed for its execution, in microseconds.",
+ "minimum": 0
+ },
+ {
+ "type": "array",
+ "description": "The arguments of the command.",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "string",
+ "description": "Client IP address and port."
+ },
+ {
+ "type": "string",
+ "description": "Client name if set via the CLIENT SETNAME command."
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/slowlog-help.json b/src/commands/slowlog-help.json
new file mode 100644
index 0000000..dde8fd4
--- /dev/null
+++ b/src/commands/slowlog-help.json
@@ -0,0 +1,22 @@
+{
+ "HELP": {
+ "summary": "Show helpful text about the different subcommands",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "6.2.0",
+ "arity": 2,
+ "container": "SLOWLOG",
+ "function": "slowlogCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/slowlog-len.json b/src/commands/slowlog-len.json
new file mode 100644
index 0000000..717a8ad
--- /dev/null
+++ b/src/commands/slowlog-len.json
@@ -0,0 +1,26 @@
+{
+ "LEN": {
+ "summary": "Returns the number of entries in the slow log.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.2.12",
+ "arity": 2,
+ "container": "SLOWLOG",
+ "function": "slowlogCommand",
+ "command_flags": [
+ "ADMIN",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:AGG_SUM",
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of entries in the slow log.",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/slowlog-reset.json b/src/commands/slowlog-reset.json
new file mode 100644
index 0000000..cfc1e4d
--- /dev/null
+++ b/src/commands/slowlog-reset.json
@@ -0,0 +1,23 @@
+{
+ "RESET": {
+ "summary": "Clears all entries from the slow log.",
+ "complexity": "O(N) where N is the number of entries in the slowlog",
+ "group": "server",
+ "since": "2.2.12",
+ "arity": 2,
+ "container": "SLOWLOG",
+ "function": "slowlogCommand",
+ "command_flags": [
+ "ADMIN",
+ "LOADING",
+ "STALE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_NODES",
+ "RESPONSE_POLICY:ALL_SUCCEEDED"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/slowlog.json b/src/commands/slowlog.json
new file mode 100644
index 0000000..1b9526b
--- /dev/null
+++ b/src/commands/slowlog.json
@@ -0,0 +1,9 @@
+{
+ "SLOWLOG": {
+ "summary": "A container for slow log commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "server",
+ "since": "2.2.12",
+ "arity": -2
+ }
+}
diff --git a/src/commands/smembers.json b/src/commands/smembers.json
new file mode 100644
index 0000000..c511408
--- /dev/null
+++ b/src/commands/smembers.json
@@ -0,0 +1,54 @@
+{
+ "SMEMBERS": {
+ "summary": "Returns all members of a set.",
+ "complexity": "O(N) where N is the set cardinality.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "sinterCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "All elements of the set.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/smismember.json b/src/commands/smismember.json
new file mode 100644
index 0000000..dbc1ddc
--- /dev/null
+++ b/src/commands/smismember.json
@@ -0,0 +1,66 @@
+{
+ "SMISMEMBER": {
+ "summary": "Determines whether multiple members belong to a set.",
+ "complexity": "O(N) where N is the number of elements being checked for membership",
+ "group": "set",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "smismemberCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List representing the membership of the given elements, in the same order as they are requested.",
+ "minItems": 1,
+ "items": {
+ "oneOf": [
+ {
+ "const": 0,
+ "description": "Not a member of the set or the key does not exist."
+ },
+ {
+ "const": 1,
+ "description": "A member of the set."
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/smove.json b/src/commands/smove.json
new file mode 100644
index 0000000..9521bb3
--- /dev/null
+++ b/src/commands/smove.json
@@ -0,0 +1,84 @@
+{
+ "SMOVE": {
+ "summary": "Moves a member from one set to another.",
+ "complexity": "O(1)",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "smoveCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "const": 1,
+ "description": "Element is moved."
+ },
+ {
+ "const": 0,
+ "description": "The element is not a member of source and no operation was performed."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "source",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sort.json b/src/commands/sort.json
new file mode 100644
index 0000000..d5f6511
--- /dev/null
+++ b/src/commands/sort.json
@@ -0,0 +1,162 @@
+{
+ "SORT": {
+ "summary": "Sorts the elements in a list, a set, or a sorted set, optionally storing the result.",
+ "complexity": "O(N+M*log(M)) where N is the number of elements in the list or set to sort, and M the number of returned elements. When the elements are not sorted, complexity is O(N).",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "sortCommand",
+ "get_keys_function": "sortGetKeys",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SET",
+ "SORTEDSET",
+ "LIST",
+ "DANGEROUS"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "notes": "For the optional BY/GET keyword. It is marked 'unknown' because the key names derive from the content of the key we sort",
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "unknown": null
+ },
+ "find_keys": {
+ "unknown": null
+ }
+ },
+ {
+ "notes": "For the optional STORE keyword. It is marked 'unknown' because the keyword can appear anywhere in the argument array",
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "unknown": null
+ },
+ "find_keys": {
+ "unknown": null
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "token": "BY",
+ "name": "by-pattern",
+ "display": "pattern",
+ "type": "pattern",
+ "key_spec_index": 1,
+ "optional": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "token": "GET",
+ "name": "get-pattern",
+ "display": "pattern",
+ "key_spec_index": 1,
+ "type": "pattern",
+ "optional": true,
+ "multiple": true,
+ "multiple_token": true
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "sorting",
+ "token": "ALPHA",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "STORE",
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 2,
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "when the store option is specified the command returns the number of sorted elements in the destination list",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "when not passing the store option the command returns a list of sorted elements",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "description": "GET option is specified, but no object was found",
+ "type": "null"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/sort_ro.json b/src/commands/sort_ro.json
new file mode 100644
index 0000000..04cc3c8
--- /dev/null
+++ b/src/commands/sort_ro.json
@@ -0,0 +1,132 @@
+{
+ "SORT_RO": {
+ "summary": "Returns the sorted elements of a list, a set, or a sorted set.",
+ "complexity": "O(N+M*log(M)) where N is the number of elements in the list or set to sort, and M the number of returned elements. When the elements are not sorted, complexity is O(N).",
+ "group": "generic",
+ "since": "7.0.0",
+ "arity": -2,
+ "function": "sortroCommand",
+ "get_keys_function": "sortROGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET",
+ "SORTEDSET",
+ "LIST",
+ "DANGEROUS"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "notes": "For the optional BY/GET keyword. It is marked 'unknown' because the key names derive from the content of the key we sort",
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "unknown": null
+ },
+ "find_keys": {
+ "unknown": null
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "token": "BY",
+ "name": "by-pattern",
+ "display": "pattern",
+ "type": "pattern",
+ "key_spec_index": 1,
+ "optional": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "token": "GET",
+ "name": "get-pattern",
+ "display": "pattern",
+ "key_spec_index": 1,
+ "type": "pattern",
+ "optional": true,
+ "multiple": true,
+ "multiple_token": true
+ },
+ {
+ "name": "order",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "asc",
+ "type": "pure-token",
+ "token": "ASC"
+ },
+ {
+ "name": "desc",
+ "type": "pure-token",
+ "token": "DESC"
+ }
+ ]
+ },
+ {
+ "name": "sorting",
+ "token": "ALPHA",
+ "type": "pure-token",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "a list of sorted elements",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "description": "GET option is specified, but no object was found",
+ "type": "null"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/spop.json b/src/commands/spop.json
new file mode 100644
index 0000000..c3954be
--- /dev/null
+++ b/src/commands/spop.json
@@ -0,0 +1,80 @@
+{
+ "SPOP": {
+ "summary": "Returns one or more random members from a set after removing them. Deletes the set if the last member was popped.",
+ "complexity": "Without the count argument O(1), otherwise O(N) where N is the value of the passed count.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "spopCommand",
+ "history": [
+ [
+ "3.2.0",
+ "Added the `count` argument."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "The key does not exist."
+ },
+ {
+ "type": "string",
+ "description": "The removed member when 'COUNT' is not given."
+ },
+ {
+ "type": "array",
+ "description": "List to the removed members when 'COUNT' is given.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "3.2.0"
+ }
+ ]
+ }
+}
diff --git a/src/commands/spublish.json b/src/commands/spublish.json
new file mode 100644
index 0000000..16c948c
--- /dev/null
+++ b/src/commands/spublish.json
@@ -0,0 +1,51 @@
+{
+ "SPUBLISH": {
+ "summary": "Post a message to a shard channel",
+ "complexity": "O(N) where N is the number of clients subscribed to the receiving shard channel.",
+ "group": "pubsub",
+ "since": "7.0.0",
+ "arity": 3,
+ "function": "spublishCommand",
+ "command_flags": [
+ "PUBSUB",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "MAY_REPLICATE"
+ ],
+ "arguments": [
+ {
+ "name": "shardchannel",
+ "type": "string"
+ },
+ {
+ "name": "message",
+ "type": "string"
+ }
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "NOT_KEY"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/srandmember.json b/src/commands/srandmember.json
new file mode 100644
index 0000000..4ba2b75
--- /dev/null
+++ b/src/commands/srandmember.json
@@ -0,0 +1,83 @@
+{
+ "SRANDMEMBER": {
+ "summary": "Get one or multiple random members from a set",
+ "complexity": "Without the count argument O(1), otherwise O(N) where N is the absolute value of the passed count.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "srandmemberCommand",
+ "history": [
+ [
+ "2.6.0",
+ "Added the optional `count` argument."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "2.6.0"
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "In case `count` is not given and key doesn't exist",
+ "type": "null"
+ },
+ {
+ "description": "In case `count` is not given, randomly selected element",
+ "type": "string"
+ },
+ {
+ "description": "In case `count` is given, an array of elements",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1
+ },
+ {
+ "description": "In case `count` is given and key doesn't exist",
+ "type": "array",
+ "maxItems": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/srem.json b/src/commands/srem.json
new file mode 100644
index 0000000..d7797cf
--- /dev/null
+++ b/src/commands/srem.json
@@ -0,0 +1,60 @@
+{
+ "SREM": {
+ "summary": "Removes one or more members from a set. Deletes the set if the last member was removed.",
+ "complexity": "O(N) where N is the number of members to be removed.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "sremCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple `member` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of members that were removed from the set, not including non existing members.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sscan.json b/src/commands/sscan.json
new file mode 100644
index 0000000..b221c94
--- /dev/null
+++ b/src/commands/sscan.json
@@ -0,0 +1,81 @@
+{
+ "SSCAN": {
+ "summary": "Iterates over members of a set.",
+ "complexity": "O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.",
+ "group": "set",
+ "since": "2.8.0",
+ "arity": -3,
+ "function": "sscanCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "cursor",
+ "type": "integer"
+ },
+ {
+ "token": "MATCH",
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "cursor and scan response in array form",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "cursor",
+ "type": "string"
+ },
+ {
+ "description": "list of set members",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/ssubscribe.json b/src/commands/ssubscribe.json
new file mode 100644
index 0000000..46373d5
--- /dev/null
+++ b/src/commands/ssubscribe.json
@@ -0,0 +1,42 @@
+{
+ "SSUBSCRIBE": {
+ "summary": "Listens for messages published to shard channels.",
+ "complexity": "O(N) where N is the number of shard channels to subscribe to.",
+ "group": "pubsub",
+ "since": "7.0.0",
+ "arity": -2,
+ "function": "ssubscribeCommand",
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "shardchannel",
+ "type": "string",
+ "multiple": true
+ }
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "NOT_KEY"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/src/commands/strlen.json b/src/commands/strlen.json
new file mode 100644
index 0000000..395a02d
--- /dev/null
+++ b/src/commands/strlen.json
@@ -0,0 +1,48 @@
+{
+ "STRLEN": {
+ "summary": "Returns the length of a string value.",
+ "complexity": "O(1)",
+ "group": "string",
+ "since": "2.2.0",
+ "arity": 2,
+ "function": "strlenCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The length of the string value stored at key, or 0 when key does not exist.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/subscribe.json b/src/commands/subscribe.json
new file mode 100644
index 0000000..bdf12b7
--- /dev/null
+++ b/src/commands/subscribe.json
@@ -0,0 +1,25 @@
+{
+ "SUBSCRIBE": {
+ "summary": "Listens for messages published to channels.",
+ "complexity": "O(N) where N is the number of channels to subscribe to.",
+ "group": "pubsub",
+ "since": "2.0.0",
+ "arity": -2,
+ "function": "subscribeCommand",
+ "history": [],
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "channel",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/substr.json b/src/commands/substr.json
new file mode 100644
index 0000000..1244183
--- /dev/null
+++ b/src/commands/substr.json
@@ -0,0 +1,60 @@
+{
+ "SUBSTR": {
+ "summary": "Returns a substring from a string value.",
+ "complexity": "O(N) where N is the length of the returned string. The complexity is ultimately determined by the returned length, but because creating a substring from an existing string is very cheap, it can be considered O(1) for small strings.",
+ "group": "string",
+ "since": "1.0.0",
+ "arity": 4,
+ "function": "getrangeCommand",
+ "deprecated_since": "2.0.0",
+ "replaced_by": "`GETRANGE`",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STRING"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "string",
+ "description": "The substring of the string value stored at key, determined by the offsets start and end (both are inclusive)."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "end",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/sunion.json b/src/commands/sunion.json
new file mode 100644
index 0000000..56f2b9e
--- /dev/null
+++ b/src/commands/sunion.json
@@ -0,0 +1,55 @@
+{
+ "SUNION": {
+ "summary": "Returns the union of multiple sets.",
+ "complexity": "O(N) where N is the total number of elements in all given sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -2,
+ "function": "sunionCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT_ORDER"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List with the members of the resulting set.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sunionstore.json b/src/commands/sunionstore.json
new file mode 100644
index 0000000..94d4e16
--- /dev/null
+++ b/src/commands/sunionstore.json
@@ -0,0 +1,73 @@
+{
+ "SUNIONSTORE": {
+ "summary": "Stores the union of multiple sets in a key.",
+ "complexity": "O(N) where N is the total number of elements in all given sets.",
+ "group": "set",
+ "since": "1.0.0",
+ "arity": -3,
+ "function": "sunionstoreCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of the elements in the resulting set.",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/sunsubscribe.json b/src/commands/sunsubscribe.json
new file mode 100644
index 0000000..2d68fc7
--- /dev/null
+++ b/src/commands/sunsubscribe.json
@@ -0,0 +1,43 @@
+{
+ "SUNSUBSCRIBE": {
+ "summary": "Stops listening to messages posted to shard channels.",
+ "complexity": "O(N) where N is the number of shard channels to unsubscribe.",
+ "group": "pubsub",
+ "since": "7.0.0",
+ "arity": -1,
+ "function": "sunsubscribeCommand",
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE"
+ ],
+ "arguments": [
+ {
+ "name": "shardchannel",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "NOT_KEY"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/src/commands/swapdb.json b/src/commands/swapdb.json
new file mode 100644
index 0000000..e98bc76
--- /dev/null
+++ b/src/commands/swapdb.json
@@ -0,0 +1,31 @@
+{
+ "SWAPDB": {
+ "summary": "Swaps two Redis databases.",
+ "complexity": "O(N) where N is the count of clients watching or blocking on keys from both databases.",
+ "group": "server",
+ "since": "4.0.0",
+ "arity": 3,
+ "function": "swapdbCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE",
+ "DANGEROUS"
+ ],
+ "arguments": [
+ {
+ "name": "index1",
+ "type": "integer"
+ },
+ {
+ "name": "index2",
+ "type": "integer"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/sync.json b/src/commands/sync.json
new file mode 100644
index 0000000..e18c337
--- /dev/null
+++ b/src/commands/sync.json
@@ -0,0 +1,15 @@
+{
+ "SYNC": {
+ "summary": "An internal command used in replication.",
+ "group": "server",
+ "since": "1.0.0",
+ "arity": 1,
+ "function": "syncCommand",
+ "command_flags": [
+ "NO_ASYNC_LOADING",
+ "ADMIN",
+ "NO_MULTI",
+ "NOSCRIPT"
+ ]
+ }
+}
diff --git a/src/commands/time.json b/src/commands/time.json
new file mode 100644
index 0000000..3161d3f
--- /dev/null
+++ b/src/commands/time.json
@@ -0,0 +1,28 @@
+{
+ "TIME": {
+ "summary": "Returns the server time.",
+ "complexity": "O(1)",
+ "group": "server",
+ "since": "2.6.0",
+ "arity": 1,
+ "function": "timeCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE",
+ "FAST"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Array containing two elements: Unix time in seconds and microseconds.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": {
+ "type": "string",
+ "pattern": "[0-9]+"
+ }
+ }
+ }
+}
diff --git a/src/commands/touch.json b/src/commands/touch.json
new file mode 100644
index 0000000..fd1dc61
--- /dev/null
+++ b/src/commands/touch.json
@@ -0,0 +1,53 @@
+{
+ "TOUCH": {
+ "summary": "Returns the number of existing keys out of those specified after updating the time they were last accessed.",
+ "complexity": "O(N) where N is the number of keys that will be touched.",
+ "group": "generic",
+ "since": "3.2.1",
+ "arity": -2,
+ "function": "touchCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of touched keys",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/ttl.json b/src/commands/ttl.json
new file mode 100644
index 0000000..9f5ab89
--- /dev/null
+++ b/src/commands/ttl.json
@@ -0,0 +1,70 @@
+{
+ "TTL": {
+ "summary": "Returns the expiration time in seconds of a key.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "ttlCommand",
+ "history": [
+ [
+ "2.8.0",
+ "Added the -2 reply."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "TTL in seconds.",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "The key exists but has no associated expire.",
+ "const": -1
+ },
+ {
+ "description": "The key does not exist.",
+ "const": -2
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/type.json b/src/commands/type.json
new file mode 100644
index 0000000..e8353b9
--- /dev/null
+++ b/src/commands/type.json
@@ -0,0 +1,55 @@
+{
+ "TYPE": {
+ "summary": "Determines the type of value stored at a key.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "1.0.0",
+ "arity": 2,
+ "function": "typeCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Key doesn't exist",
+ "type": "null"
+ },
+ {
+ "description": "Type of the key",
+ "type": "string"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/unlink.json b/src/commands/unlink.json
new file mode 100644
index 0000000..a05704a
--- /dev/null
+++ b/src/commands/unlink.json
@@ -0,0 +1,54 @@
+{
+ "UNLINK": {
+ "summary": "Asynchronously deletes one or more keys.",
+ "complexity": "O(1) for each key removed regardless of its size. Then the command does O(N) work in a different thread in order to reclaim memory, where N is the number of allocations the deleted objects where composed of.",
+ "group": "generic",
+ "since": "4.0.0",
+ "arity": -2,
+ "function": "unlinkCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "KEYSPACE"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:MULTI_SHARD",
+ "RESPONSE_POLICY:AGG_SUM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RM",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "the number of keys that were unlinked",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/unsubscribe.json b/src/commands/unsubscribe.json
new file mode 100644
index 0000000..e8586bc
--- /dev/null
+++ b/src/commands/unsubscribe.json
@@ -0,0 +1,25 @@
+{
+ "UNSUBSCRIBE": {
+ "summary": "Stops listening to messages posted to channels.",
+ "complexity": "O(N) where N is the number of channels to unsubscribe.",
+ "group": "pubsub",
+ "since": "2.0.0",
+ "arity": -1,
+ "function": "unsubscribeCommand",
+ "command_flags": [
+ "PUBSUB",
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "SENTINEL"
+ ],
+ "arguments": [
+ {
+ "name": "channel",
+ "type": "string",
+ "optional": true,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/unwatch.json b/src/commands/unwatch.json
new file mode 100644
index 0000000..28cc5f0
--- /dev/null
+++ b/src/commands/unwatch.json
@@ -0,0 +1,23 @@
+{
+ "UNWATCH": {
+ "summary": "Forgets about watched keys of a transaction.",
+ "complexity": "O(1)",
+ "group": "transactions",
+ "since": "2.2.0",
+ "arity": 1,
+ "function": "unwatchCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "TRANSACTION"
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/wait.json b/src/commands/wait.json
new file mode 100644
index 0000000..f936b92
--- /dev/null
+++ b/src/commands/wait.json
@@ -0,0 +1,34 @@
+{
+ "WAIT": {
+ "summary": "Blocks until the asynchronous replication of all preceding write commands sent by the connection is completed.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "3.0.0",
+ "arity": 3,
+ "function": "waitCommand",
+ "command_flags": [
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:AGG_MIN"
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of replicas reached by all the writes performed in the context of the current connection.",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "numreplicas",
+ "type": "integer"
+ },
+ {
+ "name": "timeout",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/waitaof.json b/src/commands/waitaof.json
new file mode 100644
index 0000000..735a8f2
--- /dev/null
+++ b/src/commands/waitaof.json
@@ -0,0 +1,52 @@
+{
+ "WAITAOF": {
+ "summary": "Blocks until all of the preceding write commands sent by the connection are written to the append-only file of the master and/or replicas.",
+ "complexity": "O(1)",
+ "group": "generic",
+ "since": "7.2.0",
+ "arity": 4,
+ "function": "waitaofCommand",
+ "command_flags": [
+ "NOSCRIPT"
+ ],
+ "acl_categories": [
+ "CONNECTION"
+ ],
+ "command_tips": [
+ "REQUEST_POLICY:ALL_SHARDS",
+ "RESPONSE_POLICY:AGG_MIN"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Number of local and remote AOF files in sync.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Number of local AOF files.",
+ "type": "integer",
+ "minimum": 0
+ },
+ {
+ "description": "Number of replica AOF files.",
+ "type": "number",
+ "minimum": 0
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numlocal",
+ "type": "integer"
+ },
+ {
+ "name": "numreplicas",
+ "type": "integer"
+ },
+ {
+ "name": "timeout",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/watch.json b/src/commands/watch.json
new file mode 100644
index 0000000..9faab2b
--- /dev/null
+++ b/src/commands/watch.json
@@ -0,0 +1,50 @@
+{
+ "WATCH": {
+ "summary": "Monitors changes to keys to determine the execution of a transaction.",
+ "complexity": "O(1) for every key.",
+ "group": "transactions",
+ "since": "2.2.0",
+ "arity": -2,
+ "function": "watchCommand",
+ "command_flags": [
+ "NOSCRIPT",
+ "LOADING",
+ "STALE",
+ "FAST",
+ "ALLOW_BUSY"
+ ],
+ "acl_categories": [
+ "TRANSACTION"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/xack.json b/src/commands/xack.json
new file mode 100644
index 0000000..4a1e92b
--- /dev/null
+++ b/src/commands/xack.json
@@ -0,0 +1,58 @@
+{
+ "XACK": {
+ "summary": "Returns the number of messages that were successfully acknowledged by the consumer group member of a stream.",
+ "complexity": "O(1) for each message ID processed.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -4,
+ "function": "xackCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "ID",
+ "type": "string",
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "The command returns the number of messages successfully acknowledged. Certain message IDs may no longer be part of the PEL (for example because they have already been acknowledged), and XACK will not count them as successfully acknowledged.",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/xadd.json b/src/commands/xadd.json
new file mode 100644
index 0000000..2188052
--- /dev/null
+++ b/src/commands/xadd.json
@@ -0,0 +1,161 @@
+{
+ "XADD": {
+ "summary": "Appends a new message to a stream. Creates the key if it doesn't exist.",
+ "complexity": "O(1) when adding a new entry, O(N) when trimming where N being the number of entries evicted.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -5,
+ "function": "xaddCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `NOMKSTREAM` option, `MINID` trimming strategy and the `LIMIT` option."
+ ],
+ [
+ "7.0.0",
+ "Added support for the `<ms>-*` explicit ID form."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "notes": "UPDATE instead of INSERT because of the optional trimming feature",
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "token": "NOMKSTREAM",
+ "name": "nomkstream",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "name": "trim",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "strategy",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "maxlen",
+ "type": "pure-token",
+ "token": "MAXLEN"
+ },
+ {
+ "name": "minid",
+ "type": "pure-token",
+ "token": "MINID",
+ "since": "6.2.0"
+ }
+ ]
+ },
+ {
+ "name": "operator",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "equal",
+ "type": "pure-token",
+ "token": "="
+ },
+ {
+ "name": "approximately",
+ "type": "pure-token",
+ "token": "~"
+ }
+ ]
+ },
+ {
+ "name": "threshold",
+ "type": "string"
+ },
+ {
+ "token": "LIMIT",
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ },
+ {
+ "name": "id-selector",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "auto-id",
+ "type": "pure-token",
+ "token": "*"
+ },
+ {
+ "name": "id",
+ "type": "string"
+ }
+ ]
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "field",
+ "type": "string"
+ },
+ {
+ "name": "value",
+ "type": "string"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf":[
+ {
+ "description": "The ID of the added entry. The ID is the one auto-generated if * is passed as ID argument, otherwise the command just returns the same ID specified by the user during insertion.",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "The NOMKSTREAM option is given and the key doesn't exist.",
+ "type": "null"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xautoclaim.json b/src/commands/xautoclaim.json
new file mode 100644
index 0000000..2e8e9c1
--- /dev/null
+++ b/src/commands/xautoclaim.json
@@ -0,0 +1,158 @@
+{
+ "XAUTOCLAIM": {
+ "summary": "Changes, or acquires, ownership of messages in a consumer group, as if the messages were delivered to as consumer group member.",
+ "complexity": "O(1) if COUNT is small.",
+ "group": "stream",
+ "since": "6.2.0",
+ "arity": -6,
+ "function": "xautoclaimCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added an element to the reply array, containing deleted entries the command cleared from the PEL"
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "Claimed stream entries (with data, if `JUSTID` was not given).",
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "Cursor for next call.",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "description": "Entry IDs which no longer exist in the stream, and were deleted from the PEL in which they were found.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ }
+ }
+ ]
+ },
+ {
+ "description": "Claimed stream entries (without data, if `JUSTID` was given).",
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "Cursor for next call.",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ }
+ },
+ {
+ "description": "Entry IDs which no longer exist in the stream, and were deleted from the PEL in which they were found.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "consumer",
+ "type": "string"
+ },
+ {
+ "name": "min-idle-time",
+ "type": "string"
+ },
+ {
+ "name": "start",
+ "type": "string"
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "justid",
+ "token": "JUSTID",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/xclaim.json b/src/commands/xclaim.json
new file mode 100644
index 0000000..5c44746
--- /dev/null
+++ b/src/commands/xclaim.json
@@ -0,0 +1,138 @@
+{
+ "XCLAIM": {
+ "summary": "Changes, or acquires, ownership of a message in a consumer group, as if the message was delivered a consumer group member.",
+ "complexity": "O(log N) with N being the number of messages in the PEL of the consumer group.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -6,
+ "function": "xclaimCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "consumer",
+ "type": "string"
+ },
+ {
+ "name": "min-idle-time",
+ "type": "string"
+ },
+ {
+ "name": "ID",
+ "type": "string",
+ "multiple": true
+ },
+ {
+ "token": "IDLE",
+ "name": "ms",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "TIME",
+ "name": "unix-time-milliseconds",
+ "type": "unix-time",
+ "optional": true
+ },
+ {
+ "token": "RETRYCOUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "force",
+ "token": "FORCE",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "justid",
+ "token": "JUSTID",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "lastid",
+ "token": "LASTID",
+ "type": "string",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "Stream entries with IDs matching the specified range.",
+ "anyOf": [
+ {
+ "description": "If JUSTID option is specified, return just an array of IDs of messages successfully claimed",
+ "type": "array",
+ "items": {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ }
+ },
+ {
+ "description": "array of stream entries that contains each entry as an array of 2 elements, the Entry ID and the entry data itself",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xdel.json b/src/commands/xdel.json
new file mode 100644
index 0000000..5cf4a70
--- /dev/null
+++ b/src/commands/xdel.json
@@ -0,0 +1,54 @@
+{
+ "XDEL": {
+ "summary": "Returns the number of messages after removing them from a stream.",
+ "complexity": "O(1) for each single item to delete in the stream, regardless of the stream size.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -3,
+ "function": "xdelCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "ID",
+ "type": "string",
+ "multiple": true
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of entries actually deleted",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/xgroup-create.json b/src/commands/xgroup-create.json
new file mode 100644
index 0000000..6b11a1f
--- /dev/null
+++ b/src/commands/xgroup-create.json
@@ -0,0 +1,85 @@
+{
+ "CREATE": {
+ "summary": "Creates a consumer group.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -5,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `entries_read` named argument."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "id-selector",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "id",
+ "type": "string"
+ },
+ {
+ "name": "new-id",
+ "type": "pure-token",
+ "token": "$"
+ }
+ ]
+ },
+ {
+ "token": "MKSTREAM",
+ "name": "mkstream",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "ENTRIESREAD",
+ "name": "entries-read",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/xgroup-createconsumer.json b/src/commands/xgroup-createconsumer.json
new file mode 100644
index 0000000..2f3d6a9
--- /dev/null
+++ b/src/commands/xgroup-createconsumer.json
@@ -0,0 +1,64 @@
+{
+ "CREATECONSUMER": {
+ "summary": "Creates a consumer in a consumer group.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "6.2.0",
+ "arity": 5,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "INSERT"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "consumer",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of created consumers (0 or 1)",
+ "oneOf": [
+ {
+ "const": 1
+ },
+ {
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xgroup-delconsumer.json b/src/commands/xgroup-delconsumer.json
new file mode 100644
index 0000000..12244f8
--- /dev/null
+++ b/src/commands/xgroup-delconsumer.json
@@ -0,0 +1,57 @@
+{
+ "DELCONSUMER": {
+ "summary": "Deletes a consumer from a consumer group.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 5,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "consumer",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of pending messages that were yet associated with such a consumer",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/xgroup-destroy.json b/src/commands/xgroup-destroy.json
new file mode 100644
index 0000000..c9affbd
--- /dev/null
+++ b/src/commands/xgroup-destroy.json
@@ -0,0 +1,59 @@
+{
+ "DESTROY": {
+ "summary": "Destroys a consumer group.",
+ "complexity": "O(N) where N is the number of entries in the group's pending entries list (PEL).",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 4,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of destroyed consumer groups (0 or 1)",
+ "oneOf": [
+ {
+ "const": 1
+ },
+ {
+ "const": 0
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xgroup-help.json b/src/commands/xgroup-help.json
new file mode 100644
index 0000000..3d2a738
--- /dev/null
+++ b/src/commands/xgroup-help.json
@@ -0,0 +1,25 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/xgroup-setid.json b/src/commands/xgroup-setid.json
new file mode 100644
index 0000000..76a3c79
--- /dev/null
+++ b/src/commands/xgroup-setid.json
@@ -0,0 +1,79 @@
+{
+ "SETID": {
+ "summary": "Sets the last-delivered ID of a consumer group.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -5,
+ "container": "XGROUP",
+ "function": "xgroupCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the optional `entries_read` argument."
+ ]
+ ],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "id-selector",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "id",
+ "type": "string"
+ },
+ {
+ "name": "new-id",
+ "type": "pure-token",
+ "token": "$"
+ }
+ ]
+ },
+ {
+ "name": "entriesread",
+ "display": "entries-read",
+ "token": "ENTRIESREAD",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/xgroup.json b/src/commands/xgroup.json
new file mode 100644
index 0000000..4910b7c
--- /dev/null
+++ b/src/commands/xgroup.json
@@ -0,0 +1,9 @@
+{
+ "XGROUP": {
+ "summary": "A container for consumer groups commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/xinfo-consumers.json b/src/commands/xinfo-consumers.json
new file mode 100644
index 0000000..b507e8e
--- /dev/null
+++ b/src/commands/xinfo-consumers.json
@@ -0,0 +1,80 @@
+{
+ "CONSUMERS": {
+ "summary": "Returns a list of the consumers in a consumer group.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 4,
+ "container": "XINFO",
+ "function": "xinfoCommand",
+ "history": [
+ [
+ "7.2.0",
+ "Added the `inactive` field."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ }
+ ],
+ "reply_schema": {
+ "description": "Array list of consumers",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "pending": {
+ "type": "integer"
+ },
+ "idle": {
+ "type": "integer"
+ },
+ "inactive": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/commands/xinfo-groups.json b/src/commands/xinfo-groups.json
new file mode 100644
index 0000000..a9cbe8e
--- /dev/null
+++ b/src/commands/xinfo-groups.json
@@ -0,0 +1,92 @@
+{
+ "GROUPS": {
+ "summary": "Returns a list of the consumer groups of a stream.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 3,
+ "container": "XINFO",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `entries-read` and `lag` fields"
+ ]
+ ],
+ "function": "xinfoCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "consumers": {
+ "type": "integer"
+ },
+ "pending": {
+ "type": "integer"
+ },
+ "last-delivered-id": {
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "entries-read": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ },
+ "lag": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/xinfo-help.json b/src/commands/xinfo-help.json
new file mode 100644
index 0000000..d4cbe3d
--- /dev/null
+++ b/src/commands/xinfo-help.json
@@ -0,0 +1,25 @@
+{
+ "HELP": {
+ "summary": "Returns helpful text about the different subcommands.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 2,
+ "container": "XINFO",
+ "function": "xinfoCommand",
+ "command_flags": [
+ "LOADING",
+ "STALE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "Helpful text about subcommands.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/src/commands/xinfo-stream.json b/src/commands/xinfo-stream.json
new file mode 100644
index 0000000..018826f
--- /dev/null
+++ b/src/commands/xinfo-stream.json
@@ -0,0 +1,361 @@
+{
+ "STREAM": {
+ "summary": "Returns information about a stream.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -3,
+ "container": "XINFO",
+ "history": [
+ [
+ "6.0.0",
+ "Added the `FULL` modifier."
+ ],
+ [
+ "7.0.0",
+ "Added the `max-deleted-entry-id`, `entries-added`, `recorded-first-entry-id`, `entries-read` and `lag` fields"
+ ],
+ [
+ "7.2.0",
+ "Added the `active-time` field, and changed the meaning of `seen-time`."
+ ]
+ ],
+ "function": "xinfoCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Summary form, in case `FULL` was not given.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "length": {
+ "description": "the number of entries in the stream (see `XLEN`)",
+ "type": "integer"
+ },
+ "radix-tree-keys": {
+ "description": "the number of keys in the underlying radix data structure",
+ "type": "integer"
+ },
+ "radix-tree-nodes": {
+ "description": "the number of nodes in the underlying radix data structure",
+ "type": "integer"
+ },
+ "last-generated-id": {
+ "description": "the ID of the least-recently entry that was added to the stream",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "max-deleted-entry-id": {
+ "description": "the maximal entry ID that was deleted from the stream",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "recorded-first-entry-id": {
+ "description": "cached copy of the first entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "entries-added": {
+ "description": "the count of all entries added to the stream during its lifetime",
+ "type": "integer"
+ },
+ "groups": {
+ "description": "the number of consumer groups defined for the stream",
+ "type": "integer"
+ },
+ "first-entry": {
+ "description": "the first entry of the stream",
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "last-entry": {
+ "description": "the last entry of the stream",
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "description": "Extended form, in case `FULL` was given.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "length": {
+ "description": "the number of entries in the stream (see `XLEN`)",
+ "type": "integer"
+ },
+ "radix-tree-keys": {
+ "description": "the number of keys in the underlying radix data structure",
+ "type": "integer"
+ },
+ "radix-tree-nodes": {
+ "description": "the number of nodes in the underlying radix data structure",
+ "type": "integer"
+ },
+ "last-generated-id": {
+ "description": "the ID of the least-recently entry that was added to the stream",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "max-deleted-entry-id": {
+ "description": "the maximal entry ID that was deleted from the stream",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "recorded-first-entry-id": {
+ "description": "cached copy of the first entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "entries-added": {
+ "description": "the count of all entries added to the stream during its lifetime",
+ "type": "integer"
+ },
+ "entries": {
+ "description": "all the entries of the stream",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
+ "groups": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "group name",
+ "type": "string"
+ },
+ "last-delivered-id": {
+ "description": "last entry ID that was delivered to a consumer",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ "entries-read": {
+ "description": "total number of entries ever read by consumers in the group",
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ },
+ "lag": {
+ "description": "number of entries left to be consumed from the stream",
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ },
+ "pel-count": {
+ "description": "total number of unacknowledged entries",
+ "type": "integer"
+ },
+ "pending": {
+ "description": "data about all of the unacknowledged entries",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Consumer name",
+ "type": "string"
+ },
+ {
+ "description": "Delivery timestamp",
+ "type": "integer"
+ },
+ {
+ "description": "Delivery count",
+ "type": "integer"
+ }
+ ]
+ }
+ },
+ "consumers": {
+ "description": "data about all of the consumers of the group",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "active-time": {
+ "type": "integer",
+ "description": "Last time this consumer was active (successful reading/claiming).",
+ "minimum": 0
+ },
+ "name": {
+ "description": "consumer name",
+ "type": "string"
+ },
+ "seen-time": {
+ "description": "timestamp of the last interaction attempt of the consumer",
+ "type": "integer"
+ },
+ "pel-count": {
+ "description": "number of unacknowledged entries that belong to the consumer",
+ "type": "integer"
+ },
+ "pending": {
+ "description": "data about the unacknowledged entries",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 3,
+ "maxItems": 3,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Delivery timestamp",
+ "type": "integer"
+ },
+ {
+ "description": "Delivery count",
+ "type": "integer"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "full-block",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "full",
+ "token": "FULL",
+ "type": "pure-token"
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/xinfo.json b/src/commands/xinfo.json
new file mode 100644
index 0000000..cc85bf1
--- /dev/null
+++ b/src/commands/xinfo.json
@@ -0,0 +1,9 @@
+{
+ "XINFO": {
+ "summary": "A container for stream introspection commands.",
+ "complexity": "Depends on subcommand.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -2
+ }
+}
diff --git a/src/commands/xlen.json b/src/commands/xlen.json
new file mode 100644
index 0000000..16ce72c
--- /dev/null
+++ b/src/commands/xlen.json
@@ -0,0 +1,48 @@
+{
+ "XLEN": {
+ "summary": "Return the number of messages in a stream.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": 2,
+ "function": "xlenCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of entries of the stream at key",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/xpending.json b/src/commands/xpending.json
new file mode 100644
index 0000000..a6df801
--- /dev/null
+++ b/src/commands/xpending.json
@@ -0,0 +1,160 @@
+{
+ "XPENDING": {
+ "summary": "Returns the information and entries from a stream consumer group's pending entries list.",
+ "complexity": "O(N) with N being the number of elements returned, so asking for a small fixed number of entries per call is O(1). O(M), where M is the total number of entries scanned when used with the IDLE filter. When the command returns just the summary and the list of consumers is small, it runs in O(1) time; otherwise, an additional O(N) time for iterating every consumer.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -3,
+ "function": "xpendingCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `IDLE` option and exclusive range intervals."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "Extended form, in case `start` was given.",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Consumer name",
+ "type": "string"
+ },
+ {
+ "description": "Idle time",
+ "type": "integer"
+ },
+ {
+ "description": "Delivery count",
+ "type": "integer"
+ }
+ ]
+ }
+ },
+ {
+ "description": "Summary form, in case `start` was not given.",
+ "type": "array",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": [
+ {
+ "description": "Total number of pending messages",
+ "type": "integer"
+ },
+ {
+ "description": "Minimal pending entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Maximal pending entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Consumers with pending messages",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Consumer name",
+ "type": "string"
+ },
+ {
+ "description": "Number of pending messages",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "filters",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "token": "IDLE",
+ "name": "min-idle-time",
+ "type": "integer",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "name": "start",
+ "type": "string"
+ },
+ {
+ "name": "end",
+ "type": "string"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "consumer",
+ "type": "string",
+ "optional": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/xrange.json b/src/commands/xrange.json
new file mode 100644
index 0000000..edfe2cc
--- /dev/null
+++ b/src/commands/xrange.json
@@ -0,0 +1,87 @@
+{
+ "XRANGE": {
+ "summary": "Returns the messages from a stream within a range of IDs.",
+ "complexity": "O(N) with N being the number of elements being returned. If N is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1).",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -4,
+ "function": "xrangeCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added exclusive ranges."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Stream entries with IDs matching the specified range.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Entry ID",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Data",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "string"
+ },
+ {
+ "name": "end",
+ "type": "string"
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/xread.json b/src/commands/xread.json
new file mode 100644
index 0000000..3a78ffb
--- /dev/null
+++ b/src/commands/xread.json
@@ -0,0 +1,108 @@
+{
+ "XREAD": {
+ "summary": "Returns messages from multiple streams with IDs greater than the ones requested. Blocks until a message is available otherwise.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -4,
+ "function": "xreadCommand",
+ "get_keys_function": "xreadGetKeys",
+ "command_flags": [
+ "BLOCKING",
+ "READONLY",
+ "BLOCKING"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STREAMS",
+ "startfrom": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 2
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "BLOCK",
+ "name": "milliseconds",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "streams",
+ "token": "STREAMS",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "ID",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "A map of key-value elements when each element composed of key name and the entries reported for that key",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "description": "The entries reported for that key",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "entry id",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "array of field-value pairs",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "description": "If BLOCK option is given, and a timeout occurs, or there is no stream we can serve",
+ "type": "null"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xreadgroup.json b/src/commands/xreadgroup.json
new file mode 100644
index 0000000..93e45a8
--- /dev/null
+++ b/src/commands/xreadgroup.json
@@ -0,0 +1,134 @@
+{
+ "XREADGROUP": {
+ "summary": "Returns new or historical messages from a stream for a consumer in a group. Blocks until a message is available otherwise.",
+ "complexity": "For each stream mentioned: O(M) with M being the number of elements returned. If M is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1). On the other side when XREADGROUP blocks, XADD will pay the O(N) time in order to serve the N clients blocked on the stream getting new data.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -7,
+ "function": "xreadCommand",
+ "get_keys_function": "xreadGetKeys",
+ "command_flags": [
+ "BLOCKING",
+ "WRITE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "keyword": {
+ "keyword": "STREAMS",
+ "startfrom": 4
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": -1,
+ "step": 1,
+ "limit": 2
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "token": "GROUP",
+ "name": "group-block",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "group",
+ "type": "string"
+ },
+ {
+ "name": "consumer",
+ "type": "string"
+ }
+ ]
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "token": "BLOCK",
+ "name": "milliseconds",
+ "type": "integer",
+ "optional": true
+ },
+ {
+ "name": "noack",
+ "token": "NOACK",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "name": "streams",
+ "token": "STREAMS",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "ID",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "If BLOCK option is specified and the timeout expired",
+ "type": "null"
+ },
+ {
+ "description": "A map of key-value elements when each element composed of key name and the entries reported for that key",
+ "type": "object",
+ "additionalProperties": {
+ "description": "The entries reported for that key",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Stream id",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "oneOf": [
+ {
+ "description": "Array of field-value pairs",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/xrevrange.json b/src/commands/xrevrange.json
new file mode 100644
index 0000000..a0c3e4f
--- /dev/null
+++ b/src/commands/xrevrange.json
@@ -0,0 +1,86 @@
+{
+ "XREVRANGE": {
+ "summary": "Returns the messages from a stream within a range of IDs in reverse order.",
+ "complexity": "O(N) with N being the number of elements returned. If N is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1).",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -4,
+ "function": "xrevrangeCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added exclusive ranges."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "end",
+ "type": "string"
+ },
+ {
+ "name": "start",
+ "type": "string"
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "An array of the entries with IDs matching the specified range",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Stream id",
+ "type": "string",
+ "pattern": "[0-9]+-[0-9]+"
+ },
+ {
+ "description": "Array of field-value pairs",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/commands/xsetid.json b/src/commands/xsetid.json
new file mode 100644
index 0000000..4607037
--- /dev/null
+++ b/src/commands/xsetid.json
@@ -0,0 +1,72 @@
+{
+ "XSETID": {
+ "summary": "An internal command for replicating stream values.",
+ "complexity": "O(1)",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -3,
+ "function": "xsetidCommand",
+ "history": [
+ [
+ "7.0.0",
+ "Added the `entries_added` and `max_deleted_entry_id` arguments."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "last-id",
+ "type": "string"
+ },
+ {
+ "name": "entries-added",
+ "token": "ENTRIESADDED",
+ "type": "integer",
+ "optional": true,
+ "since": "7.0.0"
+ },
+ {
+ "name": "max-deleted-id",
+ "token": "MAXDELETEDID",
+ "type": "string",
+ "optional": true,
+ "since": "7.0.0"
+ }
+ ],
+ "reply_schema": {
+ "const": "OK"
+ }
+ }
+}
diff --git a/src/commands/xtrim.json b/src/commands/xtrim.json
new file mode 100644
index 0000000..0b79cd4
--- /dev/null
+++ b/src/commands/xtrim.json
@@ -0,0 +1,108 @@
+{
+ "XTRIM": {
+ "summary": "Deletes messages from the beginning of a stream.",
+ "complexity": "O(N), with N being the number of evicted entries. Constant times are very small however, since entries are organized in macro nodes containing multiple entries that can be released with a single deallocation.",
+ "group": "stream",
+ "since": "5.0.0",
+ "arity": -4,
+ "function": "xtrimCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `MINID` trimming strategy and the `LIMIT` option."
+ ]
+ ],
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "STREAM"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "trim",
+ "type": "block",
+ "arguments": [
+ {
+ "name": "strategy",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "maxlen",
+ "type": "pure-token",
+ "token": "MAXLEN"
+ },
+ {
+ "name": "minid",
+ "type": "pure-token",
+ "token": "MINID",
+ "since": "6.2.0"
+ }
+ ]
+ },
+ {
+ "name": "operator",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "equal",
+ "type": "pure-token",
+ "token": "="
+ },
+ {
+ "name": "approximately",
+ "type": "pure-token",
+ "token": "~"
+ }
+ ]
+ },
+ {
+ "name": "threshold",
+ "type": "string"
+ },
+ {
+ "token": "LIMIT",
+ "name": "count",
+ "type": "integer",
+ "optional": true,
+ "since": "6.2.0"
+ }
+ ]
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of entries deleted from the stream.",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+}
diff --git a/src/commands/zadd.json b/src/commands/zadd.json
new file mode 100644
index 0000000..d489ee4
--- /dev/null
+++ b/src/commands/zadd.json
@@ -0,0 +1,144 @@
+{
+ "ZADD": {
+ "summary": "Adds one or more members to a sorted set, or updates their scores. Creates the key if it doesn't exist.",
+ "complexity": "O(log(N)) for each item added, where N is the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": -4,
+ "function": "zaddCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple elements."
+ ],
+ [
+ "3.0.2",
+ "Added the `XX`, `NX`, `CH` and `INCR` options."
+ ],
+ [
+ "6.2.0",
+ "Added the `GT` and `LT` options."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf":[
+ {
+ "description": "Operation was aborted (conflict with one of the `XX`/`NX`/`LT`/`GT` options).",
+ "type": "null"
+ },
+ {
+ "description": "The number of new members (when the `CH` option is not used)",
+ "type": "integer"
+ },
+ {
+ "description": "The number of new or updated members (when the `CH` option is used)",
+ "type": "integer"
+ },
+ {
+ "description": "The updated score of the member (when the `INCR` option is used)",
+ "type": "number"
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "condition",
+ "type": "oneof",
+ "optional": true,
+ "since": "3.0.2",
+ "arguments": [
+ {
+ "name": "nx",
+ "type": "pure-token",
+ "token": "NX"
+ },
+ {
+ "name": "xx",
+ "type": "pure-token",
+ "token": "XX"
+ }
+ ]
+ },
+ {
+ "name": "comparison",
+ "type": "oneof",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "gt",
+ "type": "pure-token",
+ "token": "GT"
+ },
+ {
+ "name": "lt",
+ "type": "pure-token",
+ "token": "LT"
+ }
+ ]
+ },
+ {
+ "name": "change",
+ "token": "CH",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.2"
+ },
+ {
+ "name": "increment",
+ "token": "INCR",
+ "type": "pure-token",
+ "optional": true,
+ "since": "3.0.2"
+ },
+ {
+ "name": "data",
+ "type": "block",
+ "multiple": true,
+ "arguments": [
+ {
+ "name": "score",
+ "type": "double"
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zcard.json b/src/commands/zcard.json
new file mode 100644
index 0000000..58683a4
--- /dev/null
+++ b/src/commands/zcard.json
@@ -0,0 +1,47 @@
+{
+ "ZCARD": {
+ "summary": "Returns the number of members in a sorted set.",
+ "complexity": "O(1)",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": 2,
+ "function": "zcardCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The cardinality (number of elements) of the sorted set, or 0 if key does not exist",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ }
+ ]
+ }
+}
diff --git a/src/commands/zcount.json b/src/commands/zcount.json
new file mode 100644
index 0000000..0fdebd7
--- /dev/null
+++ b/src/commands/zcount.json
@@ -0,0 +1,56 @@
+{
+ "ZCOUNT": {
+ "summary": "Returns the count of members in a sorted set that have scores within a range.",
+ "complexity": "O(log(N)) with N being the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": 4,
+ "function": "zcountCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of elements in the specified score range",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "double"
+ },
+ {
+ "name": "max",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zdiff.json b/src/commands/zdiff.json
new file mode 100644
index 0000000..912d5c6
--- /dev/null
+++ b/src/commands/zdiff.json
@@ -0,0 +1,85 @@
+{
+ "ZDIFF": {
+ "summary": "Returns the difference between multiple sorted sets.",
+ "complexity": "O(L + (N-K)log(N)) worst case where L is the total number of elements in all the sets, N is the size of the first set, and K is the size of the result set.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "zdiffCommand",
+ "get_keys_function": "zunionInterDiffGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "A list of members. Returned in case `WITHSCORES` was not used.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "Members and their scores. Returned in case `WITHSCORES` was used. In RESP2 this is returned as a flat array",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zdiffstore.json b/src/commands/zdiffstore.json
new file mode 100644
index 0000000..35b7203
--- /dev/null
+++ b/src/commands/zdiffstore.json
@@ -0,0 +1,77 @@
+{
+ "ZDIFFSTORE": {
+ "summary": "Stores the difference of multiple sorted sets in a key.",
+ "complexity": "O(L + (N-K)log(N)) worst case where L is the total number of elements in all the sets, N is the size of the first set, and K is the size of the result set.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -4,
+ "function": "zdiffstoreCommand",
+ "get_keys_function": "zunionInterDiffStoreGetKeys",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of elements in the resulting sorted set at `destination`",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zincrby.json b/src/commands/zincrby.json
new file mode 100644
index 0000000..6830883
--- /dev/null
+++ b/src/commands/zincrby.json
@@ -0,0 +1,58 @@
+{
+ "ZINCRBY": {
+ "summary": "Increments the score of a member in a sorted set.",
+ "complexity": "O(log(N)) where N is the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": 4,
+ "function": "zincrbyCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The new score of `member`",
+ "type": "number"
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "increment",
+ "type": "integer"
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zinter.json b/src/commands/zinter.json
new file mode 100644
index 0000000..4828e21
--- /dev/null
+++ b/src/commands/zinter.json
@@ -0,0 +1,115 @@
+{
+ "ZINTER": {
+ "summary": "Returns the intersect of multiple sorted sets.",
+ "complexity": "O(N*K)+O(M*log(M)) worst case with N being the smallest input sorted set, K being the number of input sorted sets and M being the number of elements in the resulting sorted set.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "zinterCommand",
+ "get_keys_function": "zunionInterDiffGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "Result of intersection, containing only the member names. Returned in case `WITHSCORES` was not used.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "Result of intersection, containing members and their scores. Returned in case `WITHSCORES` was used. In RESP2 this is returned as a flat array",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "token": "WEIGHTS",
+ "name": "weight",
+ "type": "integer",
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "token": "AGGREGATE",
+ "name": "aggregate",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "sum",
+ "type": "pure-token",
+ "token": "SUM"
+ },
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zintercard.json b/src/commands/zintercard.json
new file mode 100644
index 0000000..7fdab3e
--- /dev/null
+++ b/src/commands/zintercard.json
@@ -0,0 +1,60 @@
+{
+ "ZINTERCARD": {
+ "summary": "Returns the number of members of the intersect of multiple sorted sets.",
+ "complexity": "O(N*K) worst case with N being the smallest input sorted set, K being the number of input sorted sets.",
+ "group": "sorted_set",
+ "since": "7.0.0",
+ "arity": -3,
+ "function": "zinterCardCommand",
+ "get_keys_function": "zunionInterDiffGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of elements in the resulting intersection.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zinterstore.json b/src/commands/zinterstore.json
new file mode 100644
index 0000000..5bd940c
--- /dev/null
+++ b/src/commands/zinterstore.json
@@ -0,0 +1,108 @@
+{
+ "ZINTERSTORE": {
+ "summary": "Stores the intersect of multiple sorted sets in a key.",
+ "complexity": "O(N*K)+O(M*log(M)) worst case with N being the smallest input sorted set, K being the number of input sorted sets and M being the number of elements in the resulting sorted set.",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": -4,
+ "function": "zinterstoreCommand",
+ "get_keys_function": "zunionInterDiffStoreGetKeys",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of elements in the resulting sorted set.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ },
+ {
+ "token": "WEIGHTS",
+ "name": "weight",
+ "type": "integer",
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "token": "AGGREGATE",
+ "name": "aggregate",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "sum",
+ "type": "pure-token",
+ "token": "SUM"
+ },
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zlexcount.json b/src/commands/zlexcount.json
new file mode 100644
index 0000000..8bf2884
--- /dev/null
+++ b/src/commands/zlexcount.json
@@ -0,0 +1,57 @@
+{
+ "ZLEXCOUNT": {
+ "summary": "Returns the number of members in a sorted set within a lexicographical range.",
+ "complexity": "O(log(N)) with N being the number of elements in the sorted set.",
+ "group": "sorted_set",
+ "since": "2.8.9",
+ "arity": 4,
+ "function": "zlexcountCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "Number of elements in the specified score range.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "string"
+ },
+ {
+ "name": "max",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zmpop.json b/src/commands/zmpop.json
new file mode 100644
index 0000000..86dc3ba
--- /dev/null
+++ b/src/commands/zmpop.json
@@ -0,0 +1,111 @@
+{
+ "ZMPOP": {
+ "summary": "Returns the highest- or lowest-scoring members from one or more sorted sets after removing them. Deletes the sorted set if the last member was popped.",
+ "complexity": "O(K) + O(M*log(N)) where K is the number of provided keys, N being the number of elements in the sorted set, and M being the number of elements popped.",
+ "group": "sorted_set",
+ "since": "7.0.0",
+ "arity": -4,
+ "function": "zmpopCommand",
+ "get_keys_function": "zmpopGetKeys",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "No element could be popped.",
+ "type": "null"
+ },
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Name of the key that elements were popped."
+ },
+ {
+ "type": "array",
+ "description": "Popped elements.",
+ "items": {
+ "type": "array",
+ "uniqueItems": true,
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Name of the member."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "name": "where",
+ "type": "oneof",
+ "arguments": [
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zmscore.json b/src/commands/zmscore.json
new file mode 100644
index 0000000..6a036fe
--- /dev/null
+++ b/src/commands/zmscore.json
@@ -0,0 +1,65 @@
+{
+ "ZMSCORE": {
+ "summary": "Returns the score of one or more members in a sorted set.",
+ "complexity": "O(N) where N is the number of members being requested.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "zmscoreCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "oneOf": [
+ {
+ "type": "number",
+ "description": "The score of the member (a double precision floating point number). In RESP2, this is returned as string."
+ },
+ {
+ "type": "null",
+ "description": "Member does not exist in the sorted set."
+ }
+ ]
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zpopmax.json b/src/commands/zpopmax.json
new file mode 100644
index 0000000..56d86bf
--- /dev/null
+++ b/src/commands/zpopmax.json
@@ -0,0 +1,89 @@
+{
+ "ZPOPMAX": {
+ "summary": "Returns the highest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped.",
+ "complexity": "O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.",
+ "group": "sorted_set",
+ "since": "5.0.0",
+ "arity": -2,
+ "function": "zpopmaxCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "array",
+ "description": "List of popped elements and scores when 'COUNT' isn't specified.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Popped element."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ },
+ {
+ "type": "array",
+ "description": "List of popped elements and scores when 'COUNT' is specified.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Popped element."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zpopmin.json b/src/commands/zpopmin.json
new file mode 100644
index 0000000..3fe36f3
--- /dev/null
+++ b/src/commands/zpopmin.json
@@ -0,0 +1,89 @@
+{
+ "ZPOPMIN": {
+ "summary": "Returns the lowest-scoring members from a sorted set after removing them. Deletes the sorted set if the last member was popped.",
+ "complexity": "O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.",
+ "group": "sorted_set",
+ "since": "5.0.0",
+ "arity": -2,
+ "function": "zpopminCommand",
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "ACCESS",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "array",
+ "description": "List of popped elements and scores when 'COUNT' isn't specified.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Popped element."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ },
+ {
+ "type": "array",
+ "description": "List of popped elements and scores when 'COUNT' is specified.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Popped element."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrandmember.json b/src/commands/zrandmember.json
new file mode 100644
index 0000000..13abc9a
--- /dev/null
+++ b/src/commands/zrandmember.json
@@ -0,0 +1,101 @@
+{
+ "ZRANDMEMBER": {
+ "summary": "Returns one or more random members from a sorted set.",
+ "complexity": "O(N) where N is the number of members returned",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -2,
+ "function": "zrandmemberCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "null",
+ "description": "Key does not exist."
+ },
+ {
+ "type": "string",
+ "description": "Randomly selected element when 'COUNT' is not used."
+ },
+ {
+ "type": "array",
+ "description": "Randomly selected elements when 'COUNT' is used.",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "array",
+ "description": "Randomly selected elements when 'COUNT' and 'WITHSCORES' modifiers are used.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "Element."
+ },
+ {
+ "type": "number",
+ "description": "Score."
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "options",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "count",
+ "type": "integer"
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrange.json b/src/commands/zrange.json
new file mode 100644
index 0000000..dc7af8d
--- /dev/null
+++ b/src/commands/zrange.json
@@ -0,0 +1,137 @@
+{
+ "ZRANGE": {
+ "summary": "Returns members in a sorted set within a range of indexes.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": -4,
+ "function": "zrangeCommand",
+ "history": [
+ [
+ "6.2.0",
+ "Added the `REV`, `BYSCORE`, `BYLEX` and `LIMIT` options."
+ ]
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "A list of member elements",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "Members and their scores. Returned in case `WITHSCORES` was used. In RESP2 this is returned as a flat array",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "Member",
+ "type": "string"
+ },
+ {
+ "description": "Score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "string"
+ },
+ {
+ "name": "stop",
+ "type": "string"
+ },
+ {
+ "name": "sortby",
+ "type": "oneof",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "byscore",
+ "type": "pure-token",
+ "token": "BYSCORE"
+ },
+ {
+ "name": "bylex",
+ "type": "pure-token",
+ "token": "BYLEX"
+ }
+ ]
+ },
+ {
+ "name": "rev",
+ "token": "REV",
+ "type": "pure-token",
+ "optional": true,
+ "since": "6.2.0"
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "since": "6.2.0",
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrangebylex.json b/src/commands/zrangebylex.json
new file mode 100644
index 0000000..5949b87
--- /dev/null
+++ b/src/commands/zrangebylex.json
@@ -0,0 +1,80 @@
+{
+ "ZRANGEBYLEX": {
+ "summary": "Returns members in a sorted set within a lexicographical range.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).",
+ "group": "sorted_set",
+ "since": "2.8.9",
+ "arity": -4,
+ "function": "zrangebylexCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`ZRANGE` with the `BYLEX` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of elements in the specified score range.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "string"
+ },
+ {
+ "name": "max",
+ "type": "string"
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrangebyscore.json b/src/commands/zrangebyscore.json
new file mode 100644
index 0000000..557ef1d
--- /dev/null
+++ b/src/commands/zrangebyscore.json
@@ -0,0 +1,119 @@
+{
+ "ZRANGEBYSCORE": {
+ "summary": "Returns members in a sorted set within a range of scores.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).",
+ "group": "sorted_set",
+ "since": "1.0.5",
+ "arity": -4,
+ "function": "zrangebyscoreCommand",
+ "history": [
+ [
+ "2.0.0",
+ "Added the `WITHSCORES` modifier."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`ZRANGE` with the `BYSCORE` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "array",
+ "description": "List of the elements in the specified score range, as not WITHSCORES",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Element"
+ }
+ },
+ {
+ "type": "array",
+ "description": "List of the elements and their scores in the specified score range, as WITHSCORES used",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "description": "Tuple of element and its score",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "element",
+ "type": "string"
+ },
+ {
+ "description": "score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "double"
+ },
+ {
+ "name": "max",
+ "type": "double"
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true,
+ "since": "2.0.0"
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrangestore.json b/src/commands/zrangestore.json
new file mode 100644
index 0000000..8eeaf74
--- /dev/null
+++ b/src/commands/zrangestore.json
@@ -0,0 +1,118 @@
+{
+ "ZRANGESTORE": {
+ "summary": "Stores a range of members from sorted set in a key.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements stored into the destination key.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -5,
+ "function": "zrangestoreCommand",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of elements in the resulting sorted set."
+ },
+ "arguments": [
+ {
+ "name": "dst",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "src",
+ "type": "key",
+ "key_spec_index": 1
+ },
+ {
+ "name": "min",
+ "type": "string"
+ },
+ {
+ "name": "max",
+ "type": "string"
+ },
+ {
+ "name": "sortby",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "byscore",
+ "type": "pure-token",
+ "token": "BYSCORE"
+ },
+ {
+ "name": "bylex",
+ "type": "pure-token",
+ "token": "BYLEX"
+ }
+ ]
+ },
+ {
+ "name": "rev",
+ "token": "REV",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrank.json b/src/commands/zrank.json
new file mode 100644
index 0000000..f5f427c
--- /dev/null
+++ b/src/commands/zrank.json
@@ -0,0 +1,86 @@
+{
+ "ZRANK": {
+ "summary": "Returns the index of a member in a sorted set ordered by ascending scores.",
+ "complexity": "O(log(N))",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "zrankCommand",
+ "history": [
+ [
+ "7.2.0",
+ "Added the optional `WITHSCORE` argument."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "Key does not exist or the member does not exist in the sorted set."
+ },
+ {
+ "type": "integer",
+ "description": "The rank of the member when 'WITHSCORE' is not used."
+ },
+ {
+ "type": "array",
+ "description": "The rank and score of the member when 'WITHSCORE' is used.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "name": "withscore",
+ "token": "WITHSCORE",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrem.json b/src/commands/zrem.json
new file mode 100644
index 0000000..8766124
--- /dev/null
+++ b/src/commands/zrem.json
@@ -0,0 +1,60 @@
+{
+ "ZREM": {
+ "summary": "Removes one or more members from a sorted set. Deletes the sorted set if all members were removed.",
+ "complexity": "O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": -3,
+ "function": "zremCommand",
+ "history": [
+ [
+ "2.4.0",
+ "Accepts multiple elements."
+ ]
+ ],
+ "command_flags": [
+ "WRITE",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of members removed from the sorted set, not including non existing members.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string",
+ "multiple": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zremrangebylex.json b/src/commands/zremrangebylex.json
new file mode 100644
index 0000000..169472c
--- /dev/null
+++ b/src/commands/zremrangebylex.json
@@ -0,0 +1,55 @@
+{
+ "ZREMRANGEBYLEX": {
+ "summary": "Removes members in a sorted set within a lexicographical range. Deletes the sorted set if all members were removed.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.",
+ "group": "sorted_set",
+ "since": "2.8.9",
+ "arity": 4,
+ "function": "zremrangebylexCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of elements removed."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "string"
+ },
+ {
+ "name": "max",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zremrangebyrank.json b/src/commands/zremrangebyrank.json
new file mode 100644
index 0000000..7e668e8
--- /dev/null
+++ b/src/commands/zremrangebyrank.json
@@ -0,0 +1,55 @@
+{
+ "ZREMRANGEBYRANK": {
+ "summary": "Removes members in a sorted set within a range of indexes. Deletes the sorted set if all members were removed.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": 4,
+ "function": "zremrangebyrankCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of elements removed."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "stop",
+ "type": "integer"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zremrangebyscore.json b/src/commands/zremrangebyscore.json
new file mode 100644
index 0000000..aed5d1b
--- /dev/null
+++ b/src/commands/zremrangebyscore.json
@@ -0,0 +1,55 @@
+{
+ "ZREMRANGEBYSCORE": {
+ "summary": "Removes members in a sorted set within a range of scores. Deletes the sorted set if all members were removed.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": 4,
+ "function": "zremrangebyscoreCommand",
+ "command_flags": [
+ "WRITE"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RW",
+ "DELETE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "integer",
+ "description": "Number of elements removed."
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "min",
+ "type": "double"
+ },
+ {
+ "name": "max",
+ "type": "double"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrevrange.json b/src/commands/zrevrange.json
new file mode 100644
index 0000000..116fe82
--- /dev/null
+++ b/src/commands/zrevrange.json
@@ -0,0 +1,94 @@
+{
+ "ZREVRANGE": {
+ "summary": "Returns members in a sorted set within a range of indexes in reverse order.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": -4,
+ "function": "zrevrangeCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`ZRANGE` with the `REV` argument",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "List of member elements.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "List of the members and their scores. Returned in case `WITHSCORES` was used.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "member",
+ "type": "string"
+ },
+ {
+ "description": "score",
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "start",
+ "type": "integer"
+ },
+ {
+ "name": "stop",
+ "type": "integer"
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrevrangebylex.json b/src/commands/zrevrangebylex.json
new file mode 100644
index 0000000..d1d8100
--- /dev/null
+++ b/src/commands/zrevrangebylex.json
@@ -0,0 +1,80 @@
+{
+ "ZREVRANGEBYLEX": {
+ "summary": "Returns members in a sorted set within a lexicographical range in reverse order.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).",
+ "group": "sorted_set",
+ "since": "2.8.9",
+ "arity": -4,
+ "function": "zrevrangebylexCommand",
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`ZRANGE` with the `REV` and `BYLEX` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of the elements in the specified score range.",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "max",
+ "type": "string"
+ },
+ {
+ "name": "min",
+ "type": "string"
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrevrangebyscore.json b/src/commands/zrevrangebyscore.json
new file mode 100644
index 0000000..ab04052
--- /dev/null
+++ b/src/commands/zrevrangebyscore.json
@@ -0,0 +1,118 @@
+{
+ "ZREVRANGEBYSCORE": {
+ "summary": "Returns members in a sorted set within a range of scores in reverse order.",
+ "complexity": "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).",
+ "group": "sorted_set",
+ "since": "2.2.0",
+ "arity": -4,
+ "function": "zrevrangebyscoreCommand",
+ "history": [
+ [
+ "2.1.6",
+ "`min` and `max` can be exclusive."
+ ]
+ ],
+ "deprecated_since": "6.2.0",
+ "replaced_by": "`ZRANGE` with the `REV` and `BYSCORE` arguments",
+ "doc_flags": [
+ "DEPRECATED"
+ ],
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "type": "array",
+ "description": "List of the elements in the specified score range, as not WITHSCORES",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Element"
+ }
+ },
+ {
+ "type": "array",
+ "description": "List of the elements and their scores in the specified score range, as WITHSCORES used",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "description": "Tuple of element and its score",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string",
+ "description": "element"
+ },
+ {
+ "type": "number",
+ "description": "score"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "max",
+ "type": "double"
+ },
+ {
+ "name": "min",
+ "type": "double"
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ },
+ {
+ "token": "LIMIT",
+ "name": "limit",
+ "type": "block",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "offset",
+ "type": "integer"
+ },
+ {
+ "name": "count",
+ "type": "integer"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/commands/zrevrank.json b/src/commands/zrevrank.json
new file mode 100644
index 0000000..39897ca
--- /dev/null
+++ b/src/commands/zrevrank.json
@@ -0,0 +1,86 @@
+{
+ "ZREVRANK": {
+ "summary": "Returns the index of a member in a sorted set ordered by descending scores.",
+ "complexity": "O(log(N))",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": -3,
+ "function": "zrevrankCommand",
+ "history": [
+ [
+ "7.2.0",
+ "Added the optional `WITHSCORE` argument."
+ ]
+ ],
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "null",
+ "description": "Key does not exist or the member does not exist in the sorted set."
+ },
+ {
+ "type": "integer",
+ "description": "The rank of the member when 'WITHSCORE' is not used."
+ },
+ {
+ "type": "array",
+ "description": "The rank and score of the member when 'WITHSCORE' is used.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "number"
+ }
+ ]
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ },
+ {
+ "name": "withscore",
+ "token": "WITHSCORE",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zscan.json b/src/commands/zscan.json
new file mode 100644
index 0000000..7c69ccf
--- /dev/null
+++ b/src/commands/zscan.json
@@ -0,0 +1,81 @@
+{
+ "ZSCAN": {
+ "summary": "Iterates over members and scores of a sorted set.",
+ "complexity": "O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.",
+ "group": "sorted_set",
+ "since": "2.8.0",
+ "arity": -3,
+ "function": "zscanCommand",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "command_tips": [
+ "NONDETERMINISTIC_OUTPUT"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "cursor",
+ "type": "integer"
+ },
+ {
+ "token": "MATCH",
+ "name": "pattern",
+ "type": "pattern",
+ "optional": true
+ },
+ {
+ "token": "COUNT",
+ "name": "count",
+ "type": "integer",
+ "optional": true
+ }
+ ],
+ "reply_schema": {
+ "description": "cursor and scan response in array form",
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "cursor",
+ "type": "string"
+ },
+ {
+ "description": "list of elements of the sorted set, where each even element is the member, and each odd value is its associated score",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/src/commands/zscore.json b/src/commands/zscore.json
new file mode 100644
index 0000000..5022470
--- /dev/null
+++ b/src/commands/zscore.json
@@ -0,0 +1,60 @@
+{
+ "ZSCORE": {
+ "summary": "Returns the score of a member in a sorted set.",
+ "complexity": "O(1)",
+ "group": "sorted_set",
+ "since": "1.2.0",
+ "arity": 3,
+ "function": "zscoreCommand",
+ "command_flags": [
+ "READONLY",
+ "FAST"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "type": "number",
+ "description": "The score of the member (a double precision floating point number). In RESP2, this is returned as string."
+ },
+ {
+ "type": "null",
+ "description": "Member does not exist in the sorted set, or key does not exist."
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "member",
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/src/commands/zunion.json b/src/commands/zunion.json
new file mode 100644
index 0000000..1ce3dc5
--- /dev/null
+++ b/src/commands/zunion.json
@@ -0,0 +1,115 @@
+{
+ "ZUNION": {
+ "summary": "Returns the union of multiple sorted sets.",
+ "complexity": "O(N)+O(M*log(M)) with N being the sum of the sizes of the input sorted sets, and M being the number of elements in the resulting sorted set.",
+ "group": "sorted_set",
+ "since": "6.2.0",
+ "arity": -3,
+ "function": "zunionCommand",
+ "get_keys_function": "zunionInterDiffGetKeys",
+ "command_flags": [
+ "READONLY"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "anyOf": [
+ {
+ "description": "The result of union when 'WITHSCORES' is not used.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "description": "The result of union when 'WITHSCORES' is used.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "arguments": [
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 0,
+ "multiple": true
+ },
+ {
+ "token": "WEIGHTS",
+ "name": "weight",
+ "type": "integer",
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "token": "AGGREGATE",
+ "name": "aggregate",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "sum",
+ "type": "pure-token",
+ "token": "SUM"
+ },
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ },
+ {
+ "name": "withscores",
+ "token": "WITHSCORES",
+ "type": "pure-token",
+ "optional": true
+ }
+ ]
+ }
+}
diff --git a/src/commands/zunionstore.json b/src/commands/zunionstore.json
new file mode 100644
index 0000000..65e7b54
--- /dev/null
+++ b/src/commands/zunionstore.json
@@ -0,0 +1,107 @@
+{
+ "ZUNIONSTORE": {
+ "summary": "Stores the union of multiple sorted sets in a key.",
+ "complexity": "O(N)+O(M log(M)) with N being the sum of the sizes of the input sorted sets, and M being the number of elements in the resulting sorted set.",
+ "group": "sorted_set",
+ "since": "2.0.0",
+ "arity": -4,
+ "function": "zunionstoreCommand",
+ "get_keys_function": "zunionInterDiffStoreGetKeys",
+ "command_flags": [
+ "WRITE",
+ "DENYOOM"
+ ],
+ "acl_categories": [
+ "SORTEDSET"
+ ],
+ "key_specs": [
+ {
+ "flags": [
+ "OW",
+ "UPDATE"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 1
+ }
+ },
+ "find_keys": {
+ "range": {
+ "lastkey": 0,
+ "step": 1,
+ "limit": 0
+ }
+ }
+ },
+ {
+ "flags": [
+ "RO",
+ "ACCESS"
+ ],
+ "begin_search": {
+ "index": {
+ "pos": 2
+ }
+ },
+ "find_keys": {
+ "keynum": {
+ "keynumidx": 0,
+ "firstkey": 1,
+ "step": 1
+ }
+ }
+ }
+ ],
+ "reply_schema": {
+ "description": "The number of elements in the resulting sorted set.",
+ "type": "integer"
+ },
+ "arguments": [
+ {
+ "name": "destination",
+ "type": "key",
+ "key_spec_index": 0
+ },
+ {
+ "name": "numkeys",
+ "type": "integer"
+ },
+ {
+ "name": "key",
+ "type": "key",
+ "key_spec_index": 1,
+ "multiple": true
+ },
+ {
+ "token": "WEIGHTS",
+ "name": "weight",
+ "type": "integer",
+ "optional": true,
+ "multiple": true
+ },
+ {
+ "token": "AGGREGATE",
+ "name": "aggregate",
+ "type": "oneof",
+ "optional": true,
+ "arguments": [
+ {
+ "name": "sum",
+ "type": "pure-token",
+ "token": "SUM"
+ },
+ {
+ "name": "min",
+ "type": "pure-token",
+ "token": "MIN"
+ },
+ {
+ "name": "max",
+ "type": "pure-token",
+ "token": "MAX"
+ }
+ ]
+ }
+ ]
+ }
+}