From 4708736f3b7a93fca2694dcd7a02f7d1cc99d789 Mon Sep 17 00:00:00 2001 From: Shaya Potter Date: Thu, 31 Oct 2024 18:16:59 +0200 Subject: [PATCH] new "transform arguments" API for better key and metadata extraction (#2733) * Parser support with all commands * remove "dist" from all imports for consistency * address most of my review comments * small tweak to multi type mapping handling * tweak multi commands / fix addScript cases * nits * addressed all in person review comments * revert addCommand/addScript changes to multi-commands addCommand needs to be there for sendCommand like ability within a multi. If its there, it might as well be used by createCommand() et al, to avoid repeating code. addScript is there (even though only used once), but now made private to keep the logic for bookkeeping near each other. --- package-lock.json | 2511 +++++------------ packages/bloom/lib/commands/bloom/ADD.spec.ts | 3 +- packages/bloom/lib/commands/bloom/ADD.ts | 12 +- .../bloom/lib/commands/bloom/CARD.spec.ts | 3 +- packages/bloom/lib/commands/bloom/CARD.ts | 9 +- .../bloom/lib/commands/bloom/EXISTS.spec.ts | 3 +- packages/bloom/lib/commands/bloom/EXISTS.ts | 12 +- .../bloom/lib/commands/bloom/INFO.spec.ts | 3 +- packages/bloom/lib/commands/bloom/INFO.ts | 17 +- .../bloom/lib/commands/bloom/INSERT.spec.ts | 15 +- packages/bloom/lib/commands/bloom/INSERT.ts | 28 +- .../lib/commands/bloom/LOADCHUNK.spec.ts | 3 +- .../bloom/lib/commands/bloom/LOADCHUNK.ts | 10 +- .../bloom/lib/commands/bloom/MADD.spec.ts | 3 +- packages/bloom/lib/commands/bloom/MADD.ts | 14 +- .../bloom/lib/commands/bloom/MEXISTS.spec.ts | 3 +- packages/bloom/lib/commands/bloom/MEXISTS.ts | 14 +- .../bloom/lib/commands/bloom/RESERVE.spec.ts | 9 +- packages/bloom/lib/commands/bloom/RESERVE.ts | 17 +- .../bloom/lib/commands/bloom/SCANDUMP.spec.ts | 3 +- packages/bloom/lib/commands/bloom/SCANDUMP.ts | 10 +- packages/bloom/lib/commands/bloom/index.ts | 2 +- .../commands/count-min-sketch/INCRBY.spec.ts | 5 +- .../lib/commands/count-min-sketch/INCRBY.ts | 20 +- .../commands/count-min-sketch/INFO.spec.ts | 3 +- .../lib/commands/count-min-sketch/INFO.ts | 9 +- .../count-min-sketch/INITBYDIM.spec.ts | 3 +- .../commands/count-min-sketch/INITBYDIM.ts | 10 +- .../count-min-sketch/INITBYPROB.spec.ts | 3 +- .../commands/count-min-sketch/INITBYPROB.ts | 10 +- .../commands/count-min-sketch/MERGE.spec.ts | 5 +- .../lib/commands/count-min-sketch/MERGE.ts | 24 +- .../commands/count-min-sketch/QUERY.spec.ts | 3 +- .../lib/commands/count-min-sketch/QUERY.ts | 12 +- .../lib/commands/count-min-sketch/index.ts | 2 +- .../bloom/lib/commands/cuckoo/ADD.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/ADD.ts | 12 +- .../bloom/lib/commands/cuckoo/ADDNX.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/ADDNX.ts | 12 +- .../bloom/lib/commands/cuckoo/COUNT.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/COUNT.ts | 10 +- .../bloom/lib/commands/cuckoo/DEL.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/DEL.ts | 12 +- .../bloom/lib/commands/cuckoo/EXISTS.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/EXISTS.ts | 12 +- .../bloom/lib/commands/cuckoo/INFO.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/INFO.ts | 9 +- .../bloom/lib/commands/cuckoo/INSERT.spec.ts | 3 +- packages/bloom/lib/commands/cuckoo/INSERT.ts | 25 +- .../lib/commands/cuckoo/INSERTNX.spec.ts | 3 +- .../bloom/lib/commands/cuckoo/INSERTNX.ts | 10 +- .../lib/commands/cuckoo/LOADCHUNK.spec.ts | 3 +- .../bloom/lib/commands/cuckoo/LOADCHUNK.ts | 10 +- .../bloom/lib/commands/cuckoo/RESERVE.spec.ts | 9 +- packages/bloom/lib/commands/cuckoo/RESERVE.ts | 19 +- .../lib/commands/cuckoo/SCANDUMP.spec.ts | 3 +- .../bloom/lib/commands/cuckoo/SCANDUMP.ts | 10 +- packages/bloom/lib/commands/cuckoo/index.ts | 2 +- .../bloom/lib/commands/t-digest/ADD.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/ADD.ts | 13 +- .../lib/commands/t-digest/BYRANK.spec.ts | 3 +- .../bloom/lib/commands/t-digest/BYRANK.ts | 19 +- .../lib/commands/t-digest/BYREVRANK.spec.ts | 3 +- .../bloom/lib/commands/t-digest/BYREVRANK.ts | 8 +- .../bloom/lib/commands/t-digest/CDF.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/CDF.ts | 15 +- .../lib/commands/t-digest/CREATE.spec.ts | 5 +- .../bloom/lib/commands/t-digest/CREATE.ts | 13 +- .../bloom/lib/commands/t-digest/INFO.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/INFO.ts | 9 +- .../bloom/lib/commands/t-digest/MAX.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/MAX.ts | 11 +- .../bloom/lib/commands/t-digest/MERGE.spec.ts | 9 +- packages/bloom/lib/commands/t-digest/MERGE.ts | 19 +- .../bloom/lib/commands/t-digest/MIN.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/MIN.ts | 11 +- .../lib/commands/t-digest/QUANTILE.spec.ts | 3 +- .../bloom/lib/commands/t-digest/QUANTILE.ts | 15 +- .../bloom/lib/commands/t-digest/RANK.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/RANK.ts | 17 +- .../bloom/lib/commands/t-digest/RESET.spec.ts | 3 +- packages/bloom/lib/commands/t-digest/RESET.ts | 9 +- .../lib/commands/t-digest/REVRANK.spec.ts | 3 +- .../bloom/lib/commands/t-digest/REVRANK.ts | 8 +- .../commands/t-digest/TRIMMED_MEAN.spec.ts | 3 +- .../lib/commands/t-digest/TRIMMED_MEAN.ts | 18 +- packages/bloom/lib/commands/t-digest/index.ts | 2 +- packages/bloom/lib/commands/top-k/ADD.spec.ts | 3 +- packages/bloom/lib/commands/top-k/ADD.ts | 12 +- .../bloom/lib/commands/top-k/COUNT.spec.ts | 3 +- packages/bloom/lib/commands/top-k/COUNT.ts | 12 +- .../bloom/lib/commands/top-k/INCRBY.spec.ts | 5 +- packages/bloom/lib/commands/top-k/INCRBY.ts | 20 +- .../bloom/lib/commands/top-k/INFO.spec.ts | 3 +- packages/bloom/lib/commands/top-k/INFO.ts | 11 +- .../bloom/lib/commands/top-k/LIST.spec.ts | 3 +- packages/bloom/lib/commands/top-k/LIST.ts | 9 +- .../lib/commands/top-k/LIST_WITHCOUNT.spec.ts | 3 +- .../lib/commands/top-k/LIST_WITHCOUNT.ts | 10 +- .../bloom/lib/commands/top-k/QUERY.spec.ts | 3 +- packages/bloom/lib/commands/top-k/QUERY.ts | 12 +- .../bloom/lib/commands/top-k/RESERVE.spec.ts | 5 +- packages/bloom/lib/commands/top-k/RESERVE.ts | 14 +- packages/bloom/lib/commands/top-k/index.ts | 2 +- packages/client/lib/RESP/encoder.ts | 2 +- packages/client/lib/RESP/types.ts | 9 +- packages/client/lib/client/commands-queue.ts | 8 +- packages/client/lib/client/index.spec.ts | 9 +- packages/client/lib/client/index.ts | 138 +- packages/client/lib/client/multi-command.ts | 70 +- packages/client/lib/client/parser.ts | 92 + packages/client/lib/client/pool.ts | 68 +- packages/client/lib/client/socket.ts | 2 +- packages/client/lib/cluster/index.ts | 162 +- packages/client/lib/cluster/multi-command.ts | 101 +- packages/client/lib/commander.ts | 6 +- packages/client/lib/commands/ACL_CAT.spec.ts | 5 +- packages/client/lib/commands/ACL_CAT.ts | 12 +- .../client/lib/commands/ACL_DELUSER.spec.ts | 5 +- packages/client/lib/commands/ACL_DELUSER.ts | 10 +- .../client/lib/commands/ACL_DRYRUN.spec.ts | 3 +- packages/client/lib/commands/ACL_DRYRUN.ts | 12 +- .../client/lib/commands/ACL_GENPASS.spec.ts | 5 +- packages/client/lib/commands/ACL_GENPASS.ts | 12 +- .../client/lib/commands/ACL_GETUSER.spec.ts | 3 +- packages/client/lib/commands/ACL_GETUSER.ts | 7 +- packages/client/lib/commands/ACL_LIST.spec.ts | 3 +- packages/client/lib/commands/ACL_LIST.ts | 7 +- packages/client/lib/commands/ACL_LOAD.spec.ts | 3 +- packages/client/lib/commands/ACL_LOAD.ts | 7 +- packages/client/lib/commands/ACL_LOG.spec.ts | 5 +- packages/client/lib/commands/ACL_LOG.ts | 14 +- .../client/lib/commands/ACL_LOG_RESET.spec.ts | 3 +- packages/client/lib/commands/ACL_LOG_RESET.ts | 7 +- packages/client/lib/commands/ACL_SAVE.spec.ts | 3 +- packages/client/lib/commands/ACL_SAVE.ts | 7 +- .../client/lib/commands/ACL_SETUSER.spec.ts | 5 +- packages/client/lib/commands/ACL_SETUSER.ts | 10 +- .../client/lib/commands/ACL_USERS.spec.ts | 3 +- packages/client/lib/commands/ACL_USERS.ts | 7 +- .../client/lib/commands/ACL_WHOAMI.spec.ts | 3 +- packages/client/lib/commands/ACL_WHOAMI.ts | 7 +- packages/client/lib/commands/APPEND.spec.ts | 3 +- packages/client/lib/commands/APPEND.ts | 7 +- packages/client/lib/commands/ASKING.spec.ts | 3 +- packages/client/lib/commands/ASKING.ts | 9 +- packages/client/lib/commands/AUTH.spec.ts | 5 +- packages/client/lib/commands/AUTH.ts | 15 +- .../client/lib/commands/BGREWRITEAOF.spec.ts | 3 +- packages/client/lib/commands/BGREWRITEAOF.ts | 7 +- packages/client/lib/commands/BGSAVE.spec.ts | 5 +- packages/client/lib/commands/BGSAVE.ts | 12 +- packages/client/lib/commands/BITCOUNT.spec.ts | 9 +- packages/client/lib/commands/BITCOUNT.ts | 19 +- packages/client/lib/commands/BITFIELD.spec.ts | 3 +- packages/client/lib/commands/BITFIELD.ts | 17 +- .../client/lib/commands/BITFIELD_RO.spec.ts | 5 +- packages/client/lib/commands/BITFIELD_RO.ts | 18 +- packages/client/lib/commands/BITOP.spec.ts | 5 +- packages/client/lib/commands/BITOP.ts | 11 +- packages/client/lib/commands/BITPOS.spec.ts | 11 +- packages/client/lib/commands/BITPOS.ts | 17 +- packages/client/lib/commands/BLMOVE.spec.ts | 3 +- packages/client/lib/commands/BLMOVE.ts | 16 +- packages/client/lib/commands/BLMPOP.spec.ts | 5 +- packages/client/lib/commands/BLMPOP.ts | 17 +- packages/client/lib/commands/BLPOP.spec.ts | 5 +- packages/client/lib/commands/BLPOP.ts | 15 +- packages/client/lib/commands/BRPOP.spec.ts | 5 +- packages/client/lib/commands/BRPOP.ts | 15 +- .../client/lib/commands/BRPOPLPUSH.spec.ts | 3 +- packages/client/lib/commands/BRPOPLPUSH.ts | 12 +- packages/client/lib/commands/BZMPOP.spec.ts | 5 +- packages/client/lib/commands/BZMPOP.ts | 9 +- packages/client/lib/commands/BZPOPMAX.spec.ts | 5 +- packages/client/lib/commands/BZPOPMAX.ts | 24 +- packages/client/lib/commands/BZPOPMIN.spec.ts | 5 +- packages/client/lib/commands/BZPOPMIN.ts | 11 +- .../lib/commands/CLIENT_CACHING.spec.ts | 5 +- .../client/lib/commands/CLIENT_CACHING.ts | 9 +- .../lib/commands/CLIENT_GETNAME.spec.ts | 3 +- .../client/lib/commands/CLIENT_GETNAME.ts | 10 +- .../lib/commands/CLIENT_GETREDIR.spec.ts | 3 +- .../client/lib/commands/CLIENT_GETREDIR.ts | 7 +- .../client/lib/commands/CLIENT_ID.spec.ts | 3 +- packages/client/lib/commands/CLIENT_ID.ts | 7 +- .../client/lib/commands/CLIENT_INFO.spec.ts | 3 +- packages/client/lib/commands/CLIENT_INFO.ts | 7 +- .../client/lib/commands/CLIENT_KILL.spec.ts | 23 +- packages/client/lib/commands/CLIENT_KILL.ts | 34 +- .../client/lib/commands/CLIENT_LIST.spec.ts | 7 +- packages/client/lib/commands/CLIENT_LIST.ts | 17 +- .../lib/commands/CLIENT_NO-EVICT.spec.ts | 5 +- .../client/lib/commands/CLIENT_NO-EVICT.ts | 9 +- .../lib/commands/CLIENT_NO-TOUCH.spec.ts | 5 +- .../client/lib/commands/CLIENT_NO-TOUCH.ts | 9 +- .../client/lib/commands/CLIENT_PAUSE.spec.ts | 5 +- packages/client/lib/commands/CLIENT_PAUSE.ts | 16 +- .../lib/commands/CLIENT_SETNAME.spec.ts | 3 +- .../client/lib/commands/CLIENT_SETNAME.ts | 7 +- .../lib/commands/CLIENT_TRACKING.spec.ts | 19 +- .../client/lib/commands/CLIENT_TRACKING.ts | 28 +- .../lib/commands/CLIENT_TRACKINGINFO.spec.ts | 3 +- .../lib/commands/CLIENT_TRACKINGINFO.ts | 7 +- .../lib/commands/CLIENT_UNPAUSE.spec.ts | 3 +- .../client/lib/commands/CLIENT_UNPAUSE.ts | 7 +- .../lib/commands/CLUSTER_ADDSLOTS.spec.ts | 5 +- .../client/lib/commands/CLUSTER_ADDSLOTS.ts | 12 +- .../commands/CLUSTER_ADDSLOTSRANGE.spec.ts | 5 +- .../lib/commands/CLUSTER_ADDSLOTSRANGE.ts | 13 +- .../lib/commands/CLUSTER_BUMPEPOCH.spec.ts | 3 +- .../client/lib/commands/CLUSTER_BUMPEPOCH.ts | 7 +- .../CLUSTER_COUNT-FAILURE-REPORTS.spec.ts | 3 +- .../commands/CLUSTER_COUNT-FAILURE-REPORTS.ts | 7 +- .../commands/CLUSTER_COUNTKEYSINSLOT.spec.ts | 3 +- .../lib/commands/CLUSTER_COUNTKEYSINSLOT.ts | 7 +- .../lib/commands/CLUSTER_DELSLOTS.spec.ts | 5 +- .../client/lib/commands/CLUSTER_DELSLOTS.ts | 12 +- .../commands/CLUSTER_DELSLOTSRANGE.spec.ts | 5 +- .../lib/commands/CLUSTER_DELSLOTSRANGE.ts | 13 +- .../lib/commands/CLUSTER_FAILOVER.spec.ts | 5 +- .../client/lib/commands/CLUSTER_FAILOVER.ts | 11 +- .../lib/commands/CLUSTER_FLUSHSLOTS.spec.ts | 3 +- .../client/lib/commands/CLUSTER_FLUSHSLOTS.ts | 7 +- .../lib/commands/CLUSTER_FORGET.spec.ts | 3 +- .../client/lib/commands/CLUSTER_FORGET.ts | 7 +- .../commands/CLUSTER_GETKEYSINSLOT.spec.ts | 3 +- .../lib/commands/CLUSTER_GETKEYSINSLOT.ts | 7 +- .../client/lib/commands/CLUSTER_INFO.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_INFO.ts | 7 +- .../lib/commands/CLUSTER_KEYSLOT.spec.ts | 3 +- .../client/lib/commands/CLUSTER_KEYSLOT.ts | 7 +- .../client/lib/commands/CLUSTER_LINKS.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_LINKS.ts | 7 +- .../client/lib/commands/CLUSTER_MEET.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_MEET.ts | 7 +- .../client/lib/commands/CLUSTER_MYID.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_MYID.ts | 7 +- .../lib/commands/CLUSTER_MYSHARDID.spec.ts | 3 +- .../client/lib/commands/CLUSTER_MYSHARDID.ts | 7 +- .../client/lib/commands/CLUSTER_NODES.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_NODES.ts | 7 +- .../lib/commands/CLUSTER_REPLICAS.spec.ts | 3 +- .../client/lib/commands/CLUSTER_REPLICAS.ts | 7 +- .../lib/commands/CLUSTER_REPLICATE.spec.ts | 3 +- .../client/lib/commands/CLUSTER_REPLICATE.ts | 7 +- .../client/lib/commands/CLUSTER_RESET.spec.ts | 5 +- packages/client/lib/commands/CLUSTER_RESET.ts | 11 +- .../lib/commands/CLUSTER_SAVECONFIG.spec.ts | 3 +- .../client/lib/commands/CLUSTER_SAVECONFIG.ts | 7 +- .../commands/CLUSTER_SET-CONFIG-EPOCH.spec.ts | 3 +- .../lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts | 7 +- .../lib/commands/CLUSTER_SETSLOT.spec.ts | 5 +- .../client/lib/commands/CLUSTER_SETSLOT.ts | 11 +- .../client/lib/commands/CLUSTER_SLOTS.spec.ts | 3 +- packages/client/lib/commands/CLUSTER_SLOTS.ts | 7 +- packages/client/lib/commands/COMMAND.ts | 6 +- .../client/lib/commands/COMMAND_COUNT.spec.ts | 3 +- packages/client/lib/commands/COMMAND_COUNT.ts | 7 +- .../lib/commands/COMMAND_GETKEYS.spec.ts | 3 +- .../client/lib/commands/COMMAND_GETKEYS.ts | 8 +- .../lib/commands/COMMAND_GETKEYSANDFLAGS.ts | 8 +- packages/client/lib/commands/COMMAND_INFO.ts | 7 +- .../client/lib/commands/COMMAND_LIST.spec.ts | 9 +- packages/client/lib/commands/COMMAND_LIST.ts | 11 +- .../client/lib/commands/CONFIG_GET.spec.ts | 5 +- packages/client/lib/commands/CONFIG_GET.ts | 10 +- .../lib/commands/CONFIG_RESETSTAT.spec.ts | 3 +- .../client/lib/commands/CONFIG_RESETSTAT.ts | 7 +- .../lib/commands/CONFIG_REWRITE.spec.ts | 3 +- .../client/lib/commands/CONFIG_REWRITE.ts | 7 +- .../client/lib/commands/CONFIG_SET.spec.ts | 5 +- packages/client/lib/commands/CONFIG_SET.ts | 14 +- packages/client/lib/commands/COPY.spec.ts | 9 +- packages/client/lib/commands/COPY.ts | 13 +- packages/client/lib/commands/DBSIZE.spec.ts | 3 +- packages/client/lib/commands/DBSIZE.ts | 7 +- packages/client/lib/commands/DECR.spec.ts | 3 +- packages/client/lib/commands/DECR.ts | 7 +- packages/client/lib/commands/DECRBY.spec.ts | 3 +- packages/client/lib/commands/DECRBY.ts | 8 +- packages/client/lib/commands/DEL.spec.ts | 5 +- packages/client/lib/commands/DEL.ts | 9 +- packages/client/lib/commands/DISCARD.spec.ts | 3 +- packages/client/lib/commands/DISCARD.ts | 5 +- packages/client/lib/commands/DUMP.spec.ts | 9 + packages/client/lib/commands/DUMP.ts | 7 +- packages/client/lib/commands/ECHO.spec.ts | 3 +- packages/client/lib/commands/ECHO.ts | 7 +- packages/client/lib/commands/EVAL.spec.ts | 3 +- packages/client/lib/commands/EVAL.ts | 22 +- packages/client/lib/commands/EVALSHA.spec.ts | 3 +- packages/client/lib/commands/EVALSHA.ts | 8 +- .../client/lib/commands/EVALSHA_RO.spec.ts | 3 +- packages/client/lib/commands/EVALSHA_RO.ts | 8 +- packages/client/lib/commands/EVAL_RO.spec.ts | 3 +- packages/client/lib/commands/EVAL_RO.ts | 8 +- packages/client/lib/commands/EXISTS.spec.ts | 7 +- packages/client/lib/commands/EXISTS.ts | 10 +- packages/client/lib/commands/EXPIRE.spec.ts | 5 +- packages/client/lib/commands/EXPIRE.ts | 14 +- packages/client/lib/commands/EXPIREAT.spec.ts | 7 +- packages/client/lib/commands/EXPIREAT.ts | 14 +- .../client/lib/commands/EXPIRETIME.spec.ts | 3 +- packages/client/lib/commands/EXPIRETIME.ts | 7 +- packages/client/lib/commands/FAILOVER.spec.ts | 13 +- packages/client/lib/commands/FAILOVER.ts | 15 +- packages/client/lib/commands/FCALL.spec.ts | 3 +- packages/client/lib/commands/FCALL.ts | 8 +- packages/client/lib/commands/FCALL_RO.spec.ts | 3 +- packages/client/lib/commands/FCALL_RO.ts | 8 +- packages/client/lib/commands/FLUSHALL.spec.ts | 7 +- packages/client/lib/commands/FLUSHALL.ts | 12 +- packages/client/lib/commands/FLUSHDB.spec.ts | 7 +- packages/client/lib/commands/FLUSHDB.ts | 12 +- .../lib/commands/FUNCTION_DELETE.spec.ts | 3 +- .../client/lib/commands/FUNCTION_DELETE.ts | 7 +- .../client/lib/commands/FUNCTION_DUMP.spec.ts | 3 +- packages/client/lib/commands/FUNCTION_DUMP.ts | 7 +- .../lib/commands/FUNCTION_FLUSH.spec.ts | 5 +- .../client/lib/commands/FUNCTION_FLUSH.ts | 13 +- .../client/lib/commands/FUNCTION_KILL.spec.ts | 3 +- packages/client/lib/commands/FUNCTION_KILL.ts | 7 +- .../client/lib/commands/FUNCTION_LIST.spec.ts | 5 +- packages/client/lib/commands/FUNCTION_LIST.ts | 13 +- .../commands/FUNCTION_LIST_WITHCODE.spec.ts | 5 +- .../lib/commands/FUNCTION_LIST_WITHCODE.ts | 9 +- .../client/lib/commands/FUNCTION_LOAD.spec.ts | 10 +- packages/client/lib/commands/FUNCTION_LOAD.ts | 15 +- .../lib/commands/FUNCTION_RESTORE.spec.ts | 5 +- .../client/lib/commands/FUNCTION_RESTORE.ts | 11 +- .../lib/commands/FUNCTION_STATS.spec.ts | 3 +- .../client/lib/commands/FUNCTION_STATS.ts | 7 +- packages/client/lib/commands/GEOADD.spec.ts | 13 +- packages/client/lib/commands/GEOADD.ts | 27 +- packages/client/lib/commands/GEODIST.spec.ts | 5 +- packages/client/lib/commands/GEODIST.ts | 13 +- packages/client/lib/commands/GEOHASH.spec.ts | 5 +- packages/client/lib/commands/GEOHASH.ts | 14 +- packages/client/lib/commands/GEOPOS.spec.ts | 5 +- packages/client/lib/commands/GEOPOS.ts | 14 +- .../client/lib/commands/GEORADIUS.spec.ts | 3 +- packages/client/lib/commands/GEORADIUS.ts | 27 +- .../lib/commands/GEORADIUSBYMEMBER.spec.ts | 3 +- .../client/lib/commands/GEORADIUSBYMEMBER.ts | 33 +- .../lib/commands/GEORADIUSBYMEMBER_RO.spec.ts | 3 +- .../lib/commands/GEORADIUSBYMEMBER_RO.ts | 10 +- .../GEORADIUSBYMEMBER_RO_WITH.spec.ts | 3 +- .../lib/commands/GEORADIUSBYMEMBER_RO_WITH.ts | 10 +- .../commands/GEORADIUSBYMEMBER_STORE.spec.ts | 5 +- .../lib/commands/GEORADIUSBYMEMBER_STORE.ts | 18 +- .../commands/GEORADIUSBYMEMBER_WITH.spec.ts | 3 +- .../lib/commands/GEORADIUSBYMEMBER_WITH.ts | 41 +- .../client/lib/commands/GEORADIUS_RO.spec.ts | 3 +- packages/client/lib/commands/GEORADIUS_RO.ts | 9 +- .../lib/commands/GEORADIUS_RO_WITH.spec.ts | 3 +- .../client/lib/commands/GEORADIUS_RO_WITH.ts | 10 +- .../lib/commands/GEORADIUS_STORE.spec.ts | 5 +- .../client/lib/commands/GEORADIUS_STORE.ts | 19 +- .../lib/commands/GEORADIUS_WITH.spec.ts | 3 +- .../client/lib/commands/GEORADIUS_WITH.ts | 39 +- .../client/lib/commands/GEOSEARCH.spec.ts | 11 +- packages/client/lib/commands/GEOSEARCH.ts | 47 +- .../lib/commands/GEOSEARCHSTORE.spec.ts | 5 +- .../client/lib/commands/GEOSEARCHSTORE.ts | 14 +- .../lib/commands/GEOSEARCH_WITH.spec.ts | 3 +- .../client/lib/commands/GEOSEARCH_WITH.ts | 12 +- packages/client/lib/commands/GET.spec.ts | 3 +- packages/client/lib/commands/GET.ts | 8 +- packages/client/lib/commands/GETBIT.spec.ts | 5 +- packages/client/lib/commands/GETBIT.ts | 9 +- packages/client/lib/commands/GETDEL.spec.ts | 3 +- packages/client/lib/commands/GETDEL.ts | 7 +- packages/client/lib/commands/GETEX.spec.ts | 21 +- packages/client/lib/commands/GETEX.ts | 25 +- packages/client/lib/commands/GETRANGE.spec.ts | 5 +- packages/client/lib/commands/GETRANGE.ts | 9 +- packages/client/lib/commands/GETSET.spec.ts | 3 +- packages/client/lib/commands/GETSET.ts | 8 +- packages/client/lib/commands/HDEL.spec.ts | 5 +- packages/client/lib/commands/HDEL.ts | 10 +- packages/client/lib/commands/HELLO.spec.ts | 11 +- packages/client/lib/commands/HELLO.ts | 13 +- packages/client/lib/commands/HEXISTS.spec.ts | 5 +- packages/client/lib/commands/HEXISTS.ts | 9 +- packages/client/lib/commands/HEXPIRE.spec.ts | 7 +- packages/client/lib/commands/HEXPIRE.ts | 30 +- .../client/lib/commands/HEXPIREAT.spec.ts | 9 +- packages/client/lib/commands/HEXPIREAT.ts | 32 +- .../client/lib/commands/HEXPIRETIME.spec.ts | 5 +- packages/client/lib/commands/HEXPIRETIME.ts | 15 +- packages/client/lib/commands/HGET.spec.ts | 3 +- packages/client/lib/commands/HGET.ts | 9 +- packages/client/lib/commands/HGETALL.ts | 8 +- packages/client/lib/commands/HINCRBY.spec.ts | 3 +- packages/client/lib/commands/HINCRBY.ts | 14 +- .../client/lib/commands/HINCRBYFLOAT.spec.ts | 3 +- packages/client/lib/commands/HINCRBYFLOAT.ts | 14 +- packages/client/lib/commands/HKEYS.spec.ts | 3 +- packages/client/lib/commands/HKEYS.ts | 8 +- packages/client/lib/commands/HLEN.spec.ts | 3 +- packages/client/lib/commands/HLEN.ts | 8 +- packages/client/lib/commands/HMGET.spec.ts | 7 +- packages/client/lib/commands/HMGET.ts | 14 +- packages/client/lib/commands/HPERSIST.spec.ts | 5 +- packages/client/lib/commands/HPERSIST.ts | 16 +- packages/client/lib/commands/HPEXPIRE.spec.ts | 7 +- packages/client/lib/commands/HPEXPIRE.ts | 25 +- .../client/lib/commands/HPEXPIREAT.spec.ts | 9 +- packages/client/lib/commands/HPEXPIREAT.ts | 18 +- .../client/lib/commands/HPEXPIRETIME.spec.ts | 5 +- packages/client/lib/commands/HPEXPIRETIME.ts | 15 +- packages/client/lib/commands/HPTTL.spec.ts | 5 +- packages/client/lib/commands/HPTTL.ts | 15 +- .../client/lib/commands/HRANDFIELD.spec.ts | 3 +- packages/client/lib/commands/HRANDFIELD.ts | 7 +- .../lib/commands/HRANDFIELD_COUNT.spec.ts | 3 +- .../client/lib/commands/HRANDFIELD_COUNT.ts | 8 +- .../commands/HRANDFIELD_COUNT_WITHVALUES.ts | 8 +- packages/client/lib/commands/HSCAN.spec.ts | 9 +- packages/client/lib/commands/HSCAN.ts | 11 +- .../lib/commands/HSCAN_NOVALUES.spec.ts | 10 +- .../client/lib/commands/HSCAN_NOVALUES.ts | 18 +- packages/client/lib/commands/HSET.spec.ts | 15 +- packages/client/lib/commands/HSET.ts | 31 +- packages/client/lib/commands/HSETNX.spec.ts | 3 +- packages/client/lib/commands/HSETNX.ts | 9 +- packages/client/lib/commands/HSTRLEN.spec.ts | 3 +- packages/client/lib/commands/HSTRLEN.ts | 9 +- packages/client/lib/commands/HTTL.spec.ts | 6 +- packages/client/lib/commands/HTTL.ts | 15 +- packages/client/lib/commands/HVALS.spec.ts | 5 +- packages/client/lib/commands/HVALS.ts | 8 +- packages/client/lib/commands/INCR.spec.ts | 3 +- packages/client/lib/commands/INCR.ts | 7 +- packages/client/lib/commands/INCRBY.spec.ts | 3 +- packages/client/lib/commands/INCRBY.ts | 8 +- .../client/lib/commands/INCRBYFLOAT.spec.ts | 3 +- packages/client/lib/commands/INCRBYFLOAT.ts | 8 +- packages/client/lib/commands/INFO.spec.ts | 5 +- packages/client/lib/commands/INFO.ts | 11 +- packages/client/lib/commands/KEYS.ts | 7 +- packages/client/lib/commands/LASTSAVE.spec.ts | 3 +- packages/client/lib/commands/LASTSAVE.ts | 7 +- .../lib/commands/LATENCY_DOCTOR.spec.ts | 3 +- .../client/lib/commands/LATENCY_DOCTOR.ts | 7 +- .../client/lib/commands/LATENCY_GRAPH.spec.ts | 3 +- packages/client/lib/commands/LATENCY_GRAPH.ts | 7 +- .../lib/commands/LATENCY_HISTORY.spec.ts | 3 +- .../client/lib/commands/LATENCY_HISTORY.ts | 7 +- .../lib/commands/LATENCY_LATEST.spec.ts | 3 +- .../client/lib/commands/LATENCY_LATEST.ts | 7 +- packages/client/lib/commands/LCS.spec.ts | 3 +- packages/client/lib/commands/LCS.ts | 8 +- packages/client/lib/commands/LCS_IDX.spec.ts | 3 +- packages/client/lib/commands/LCS_IDX.ts | 13 +- .../lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts | 3 +- .../lib/commands/LCS_IDX_WITHMATCHLEN.ts | 17 +- packages/client/lib/commands/LCS_LEN.spec.ts | 3 +- packages/client/lib/commands/LCS_LEN.ts | 15 +- packages/client/lib/commands/LINDEX.spec.ts | 3 +- packages/client/lib/commands/LINDEX.ts | 9 +- packages/client/lib/commands/LINSERT.spec.ts | 3 +- packages/client/lib/commands/LINSERT.ts | 15 +- packages/client/lib/commands/LLEN.spec.ts | 3 +- packages/client/lib/commands/LLEN.ts | 8 +- packages/client/lib/commands/LMOVE.spec.ts | 3 +- packages/client/lib/commands/LMOVE.ts | 15 +- packages/client/lib/commands/LMPOP.spec.ts | 5 +- packages/client/lib/commands/LMPOP.ts | 30 +- packages/client/lib/commands/LOLWUT.spec.ts | 7 +- packages/client/lib/commands/LOLWUT.ts | 16 +- packages/client/lib/commands/LPOP.spec.ts | 3 +- packages/client/lib/commands/LPOP.ts | 7 +- .../client/lib/commands/LPOP_COUNT.spec.ts | 3 +- packages/client/lib/commands/LPOP_COUNT.ts | 8 +- packages/client/lib/commands/LPOS.spec.ts | 11 +- packages/client/lib/commands/LPOS.ts | 24 +- .../client/lib/commands/LPOS_COUNT.spec.ts | 15 +- packages/client/lib/commands/LPOS_COUNT.ts | 20 +- packages/client/lib/commands/LPUSH.spec.ts | 5 +- packages/client/lib/commands/LPUSH.ts | 10 +- packages/client/lib/commands/LPUSHX.spec.ts | 5 +- packages/client/lib/commands/LPUSHX.ts | 10 +- packages/client/lib/commands/LRANGE.spec.ts | 5 +- packages/client/lib/commands/LRANGE.ts | 18 +- packages/client/lib/commands/LREM.spec.ts | 3 +- packages/client/lib/commands/LREM.ts | 18 +- packages/client/lib/commands/LSET.spec.ts | 3 +- packages/client/lib/commands/LSET.ts | 17 +- packages/client/lib/commands/LTRIM.spec.ts | 3 +- packages/client/lib/commands/LTRIM.ts | 17 +- .../client/lib/commands/MEMORY_DOCTOR.spec.ts | 3 +- packages/client/lib/commands/MEMORY_DOCTOR.ts | 7 +- .../lib/commands/MEMORY_MALLOC-STATS.spec.ts | 3 +- .../lib/commands/MEMORY_MALLOC-STATS.ts | 7 +- .../client/lib/commands/MEMORY_PURGE.spec.ts | 3 +- packages/client/lib/commands/MEMORY_PURGE.ts | 7 +- .../client/lib/commands/MEMORY_STATS.spec.ts | 3 +- packages/client/lib/commands/MEMORY_STATS.ts | 7 +- .../client/lib/commands/MEMORY_USAGE.spec.ts | 5 +- packages/client/lib/commands/MEMORY_USAGE.ts | 11 +- packages/client/lib/commands/MGET.spec.ts | 5 +- packages/client/lib/commands/MGET.ts | 8 +- packages/client/lib/commands/MIGRATE.spec.ts | 15 +- packages/client/lib/commands/MIGRATE.ts | 30 +- .../client/lib/commands/MODULE_LIST.spec.ts | 3 +- packages/client/lib/commands/MODULE_LIST.ts | 7 +- .../client/lib/commands/MODULE_LOAD.spec.ts | 5 +- packages/client/lib/commands/MODULE_LOAD.ts | 11 +- .../client/lib/commands/MODULE_UNLOAD.spec.ts | 3 +- packages/client/lib/commands/MODULE_UNLOAD.ts | 7 +- packages/client/lib/commands/MOVE.spec.ts | 3 +- packages/client/lib/commands/MOVE.ts | 8 +- packages/client/lib/commands/MSET.spec.ts | 7 +- packages/client/lib/commands/MSET.ts | 32 +- packages/client/lib/commands/MSETNX.spec.ts | 7 +- packages/client/lib/commands/MSETNX.ts | 9 +- .../lib/commands/OBJECT_ENCODING.spec.ts | 3 +- .../client/lib/commands/OBJECT_ENCODING.ts | 7 +- .../client/lib/commands/OBJECT_FREQ.spec.ts | 3 +- packages/client/lib/commands/OBJECT_FREQ.ts | 7 +- .../lib/commands/OBJECT_IDLETIME.spec.ts | 3 +- .../client/lib/commands/OBJECT_IDLETIME.ts | 7 +- .../lib/commands/OBJECT_REFCOUNT.spec.ts | 3 +- .../client/lib/commands/OBJECT_REFCOUNT.ts | 7 +- packages/client/lib/commands/PERSIST.spec.ts | 3 +- packages/client/lib/commands/PERSIST.ts | 7 +- packages/client/lib/commands/PEXPIRE.spec.ts | 5 +- packages/client/lib/commands/PEXPIRE.ts | 13 +- .../client/lib/commands/PEXPIREAT.spec.ts | 7 +- packages/client/lib/commands/PEXPIREAT.ts | 13 +- .../client/lib/commands/PEXPIRETIME.spec.ts | 3 +- packages/client/lib/commands/PEXPIRETIME.ts | 7 +- packages/client/lib/commands/PFADD.spec.ts | 5 +- packages/client/lib/commands/PFADD.ts | 15 +- packages/client/lib/commands/PFCOUNT.spec.ts | 5 +- packages/client/lib/commands/PFCOUNT.ts | 9 +- packages/client/lib/commands/PFMERGE.spec.ts | 5 +- packages/client/lib/commands/PFMERGE.ts | 18 +- packages/client/lib/commands/PING.spec.ts | 5 +- packages/client/lib/commands/PING.ts | 11 +- packages/client/lib/commands/PSETEX.spec.ts | 3 +- packages/client/lib/commands/PSETEX.ts | 17 +- packages/client/lib/commands/PTTL.spec.ts | 3 +- packages/client/lib/commands/PTTL.ts | 7 +- packages/client/lib/commands/PUBLISH.spec.ts | 3 +- packages/client/lib/commands/PUBLISH.ts | 7 +- .../lib/commands/PUBSUB_CHANNELS.spec.ts | 5 +- .../client/lib/commands/PUBSUB_CHANNELS.ts | 11 +- .../client/lib/commands/PUBSUB_NUMPAT.spec.ts | 3 +- packages/client/lib/commands/PUBSUB_NUMPAT.ts | 7 +- .../client/lib/commands/PUBSUB_NUMSUB.spec.ts | 7 +- packages/client/lib/commands/PUBSUB_NUMSUB.ts | 15 +- .../lib/commands/PUBSUB_SHARDCHANNELS.spec.ts | 5 +- .../lib/commands/PUBSUB_SHARDCHANNELS.ts | 11 +- .../lib/commands/PUBSUB_SHARDNUMSUB.spec.ts | 7 +- .../client/lib/commands/PUBSUB_SHARDNUMSUB.ts | 14 +- .../client/lib/commands/RANDOMKEY.spec.ts | 3 +- packages/client/lib/commands/RANDOMKEY.ts | 7 +- packages/client/lib/commands/READONLY.spec.ts | 3 +- packages/client/lib/commands/READONLY.ts | 7 +- .../client/lib/commands/READWRITE.spec.ts | 3 +- packages/client/lib/commands/READWRITE.ts | 7 +- packages/client/lib/commands/RENAME.spec.ts | 3 +- packages/client/lib/commands/RENAME.ts | 7 +- packages/client/lib/commands/RENAMENX.spec.ts | 3 +- packages/client/lib/commands/RENAMENX.ts | 7 +- .../client/lib/commands/REPLICAOF.spec.ts | 3 +- packages/client/lib/commands/REPLICAOF.ts | 7 +- .../lib/commands/RESTORE-ASKING.spec.ts | 3 +- .../client/lib/commands/RESTORE-ASKING.ts | 7 +- packages/client/lib/commands/RESTORE.spec.ts | 13 +- packages/client/lib/commands/RESTORE.ts | 19 +- packages/client/lib/commands/ROLE.spec.ts | 3 +- packages/client/lib/commands/ROLE.ts | 7 +- packages/client/lib/commands/RPOP.spec.ts | 3 +- packages/client/lib/commands/RPOP.ts | 7 +- .../client/lib/commands/RPOPLPUSH.spec.ts | 3 +- packages/client/lib/commands/RPOPLPUSH.ts | 10 +- .../client/lib/commands/RPOP_COUNT.spec.ts | 3 +- packages/client/lib/commands/RPOP_COUNT.ts | 8 +- packages/client/lib/commands/RPUSH.spec.ts | 5 +- packages/client/lib/commands/RPUSH.ts | 13 +- packages/client/lib/commands/RPUSHX.spec.ts | 5 +- packages/client/lib/commands/RPUSHX.ts | 13 +- packages/client/lib/commands/SADD.spec.ts | 5 +- packages/client/lib/commands/SADD.ts | 10 +- packages/client/lib/commands/SAVE.spec.ts | 3 +- packages/client/lib/commands/SAVE.ts | 7 +- packages/client/lib/commands/SCAN.spec.ts | 11 +- packages/client/lib/commands/SCAN.ts | 27 +- packages/client/lib/commands/SCARD.spec.ts | 3 +- packages/client/lib/commands/SCARD.ts | 8 +- .../client/lib/commands/SCRIPT_DEBUG.spec.ts | 3 +- packages/client/lib/commands/SCRIPT_DEBUG.ts | 7 +- .../client/lib/commands/SCRIPT_EXISTS.spec.ts | 5 +- packages/client/lib/commands/SCRIPT_EXISTS.ts | 10 +- .../client/lib/commands/SCRIPT_FLUSH.spec.ts | 5 +- packages/client/lib/commands/SCRIPT_FLUSH.ts | 11 +- .../client/lib/commands/SCRIPT_KILL.spec.ts | 3 +- packages/client/lib/commands/SCRIPT_KILL.ts | 7 +- .../client/lib/commands/SCRIPT_LOAD.spec.ts | 3 +- packages/client/lib/commands/SCRIPT_LOAD.ts | 7 +- packages/client/lib/commands/SDIFF.spec.ts | 7 +- packages/client/lib/commands/SDIFF.ts | 10 +- .../client/lib/commands/SDIFFSTORE.spec.ts | 5 +- packages/client/lib/commands/SDIFFSTORE.ts | 10 +- packages/client/lib/commands/SET.spec.ts | 31 +- packages/client/lib/commands/SET.ts | 38 +- packages/client/lib/commands/SETBIT.spec.ts | 3 +- packages/client/lib/commands/SETBIT.ts | 12 +- packages/client/lib/commands/SETEX.spec.ts | 3 +- packages/client/lib/commands/SETEX.ts | 17 +- packages/client/lib/commands/SETNX .spec.ts | 3 +- packages/client/lib/commands/SETNX.ts | 8 +- packages/client/lib/commands/SETRANGE.spec.ts | 3 +- packages/client/lib/commands/SETRANGE.ts | 17 +- packages/client/lib/commands/SHUTDOWN.spec.ts | 11 +- packages/client/lib/commands/SHUTDOWN.ts | 17 +- packages/client/lib/commands/SINTER.spec.ts | 7 +- packages/client/lib/commands/SINTER.ts | 10 +- .../client/lib/commands/SINTERCARD.spec.ts | 7 +- packages/client/lib/commands/SINTERCARD.ts | 19 +- .../client/lib/commands/SINTERSTORE.spec.ts | 5 +- packages/client/lib/commands/SINTERSTORE.ts | 13 +- .../client/lib/commands/SISMEMBER.spec.ts | 5 +- packages/client/lib/commands/SISMEMBER.ts | 9 +- packages/client/lib/commands/SMEMBERS.spec.ts | 5 +- packages/client/lib/commands/SMEMBERS.ts | 8 +- .../client/lib/commands/SMISMEMBER.spec.ts | 5 +- packages/client/lib/commands/SMISMEMBER.ts | 9 +- packages/client/lib/commands/SMOVE.spec.ts | 3 +- packages/client/lib/commands/SMOVE.ts | 12 +- packages/client/lib/commands/SORT.spec.ts | 17 +- packages/client/lib/commands/SORT.ts | 27 +- packages/client/lib/commands/SORT_RO.spec.ts | 17 +- packages/client/lib/commands/SORT_RO.ts | 10 +- .../client/lib/commands/SORT_STORE.spec.ts | 17 +- packages/client/lib/commands/SORT_STORE.ts | 13 +- packages/client/lib/commands/SPOP.spec.ts | 3 +- packages/client/lib/commands/SPOP.ts | 7 +- .../client/lib/commands/SPOP_COUNT.spec.ts | 3 +- packages/client/lib/commands/SPOP_COUNT.ts | 8 +- packages/client/lib/commands/SPUBLISH.spec.ts | 3 +- packages/client/lib/commands/SPUBLISH.ts | 8 +- .../client/lib/commands/SRANDMEMBER.spec.ts | 3 +- packages/client/lib/commands/SRANDMEMBER.ts | 7 +- .../lib/commands/SRANDMEMBER_COUNT.spec.ts | 3 +- .../client/lib/commands/SRANDMEMBER_COUNT.ts | 9 +- packages/client/lib/commands/SREM.spec.ts | 5 +- packages/client/lib/commands/SREM.ts | 10 +- packages/client/lib/commands/SSCAN.spec.ts | 9 +- packages/client/lib/commands/SSCAN.ts | 11 +- packages/client/lib/commands/STRLEN.spec.ts | 3 +- packages/client/lib/commands/STRLEN.ts | 8 +- packages/client/lib/commands/SUNION.spec.ts | 5 +- packages/client/lib/commands/SUNION.ts | 10 +- .../client/lib/commands/SUNIONSTORE.spec.ts | 5 +- packages/client/lib/commands/SUNIONSTORE.ts | 13 +- packages/client/lib/commands/SWAPDB.spec.ts | 3 +- packages/client/lib/commands/SWAPDB.ts | 7 +- packages/client/lib/commands/TIME.spec.ts | 3 +- packages/client/lib/commands/TIME.ts | 7 +- packages/client/lib/commands/TOUCH.spec.ts | 5 +- packages/client/lib/commands/TOUCH.ts | 9 +- packages/client/lib/commands/TTL.spec.ts | 3 +- packages/client/lib/commands/TTL.ts | 7 +- packages/client/lib/commands/TYPE.spec.ts | 5 +- packages/client/lib/commands/TYPE.ts | 8 +- packages/client/lib/commands/UNLINK.spec.ts | 5 +- packages/client/lib/commands/UNLINK.ts | 9 +- packages/client/lib/commands/WAIT.spec.ts | 3 +- packages/client/lib/commands/WAIT.ts | 7 +- packages/client/lib/commands/XACK.spec.ts | 5 +- packages/client/lib/commands/XACK.ts | 16 +- packages/client/lib/commands/XADD.spec.ts | 13 +- packages/client/lib/commands/XADD.ts | 40 +- .../lib/commands/XADD_NOMKSTREAM.spec.ts | 13 +- .../client/lib/commands/XADD_NOMKSTREAM.ts | 15 +- .../client/lib/commands/XAUTOCLAIM.spec.ts | 5 +- packages/client/lib/commands/XAUTOCLAIM.ts | 20 +- .../lib/commands/XAUTOCLAIM_JUSTID.spec.ts | 3 +- .../client/lib/commands/XAUTOCLAIM_JUSTID.ts | 9 +- packages/client/lib/commands/XCLAIM.spec.ts | 19 +- packages/client/lib/commands/XCLAIM.ts | 27 +- .../client/lib/commands/XCLAIM_JUSTID.spec.ts | 3 +- packages/client/lib/commands/XCLAIM_JUSTID.ts | 9 +- packages/client/lib/commands/XDEL.spec.ts | 5 +- packages/client/lib/commands/XDEL.ts | 10 +- .../client/lib/commands/XGROUP_CREATE.spec.ts | 7 +- packages/client/lib/commands/XGROUP_CREATE.ts | 15 +- .../commands/XGROUP_CREATECONSUMER.spec.ts | 3 +- .../lib/commands/XGROUP_CREATECONSUMER.ts | 9 +- .../lib/commands/XGROUP_DELCONSUMER.spec.ts | 3 +- .../client/lib/commands/XGROUP_DELCONSUMER.ts | 9 +- .../lib/commands/XGROUP_DESTROY.spec.ts | 3 +- .../client/lib/commands/XGROUP_DESTROY.ts | 11 +- .../client/lib/commands/XGROUP_SETID.spec.ts | 3 +- packages/client/lib/commands/XGROUP_SETID.ts | 13 +- .../lib/commands/XINFO_CONSUMERS.spec.ts | 3 +- .../client/lib/commands/XINFO_CONSUMERS.ts | 11 +- .../client/lib/commands/XINFO_GROUPS.spec.ts | 3 +- packages/client/lib/commands/XINFO_GROUPS.ts | 7 +- .../client/lib/commands/XINFO_STREAM.spec.ts | 3 +- packages/client/lib/commands/XINFO_STREAM.ts | 7 +- packages/client/lib/commands/XLEN.spec.ts | 5 +- packages/client/lib/commands/XLEN.ts | 8 +- packages/client/lib/commands/XPENDING.spec.ts | 3 +- packages/client/lib/commands/XPENDING.ts | 9 +- .../lib/commands/XPENDING_RANGE.spec.ts | 9 +- .../client/lib/commands/XPENDING_RANGE.ts | 24 +- packages/client/lib/commands/XRANGE.spec.ts | 5 +- packages/client/lib/commands/XRANGE.ts | 15 +- packages/client/lib/commands/XREAD.spec.ts | 18 +- packages/client/lib/commands/XREAD.ts | 33 +- .../client/lib/commands/XREADGROUP.spec.ts | 19 +- packages/client/lib/commands/XREADGROUP.ts | 25 +- .../client/lib/commands/XREVRANGE.spec.ts | 5 +- packages/client/lib/commands/XREVRANGE.ts | 13 +- packages/client/lib/commands/XSETID.spec.ts | 7 +- packages/client/lib/commands/XSETID.ts | 15 +- packages/client/lib/commands/XTRIM.spec.ts | 9 +- packages/client/lib/commands/XTRIM.ts | 17 +- packages/client/lib/commands/ZADD.spec.ts | 21 +- packages/client/lib/commands/ZADD.ts | 36 +- .../client/lib/commands/ZADD_INCR.spec.ts | 13 +- packages/client/lib/commands/ZADD_INCR.ts | 20 +- packages/client/lib/commands/ZCARD.spec.ts | 3 +- packages/client/lib/commands/ZCARD.ts | 8 +- packages/client/lib/commands/ZCOUNT.spec.ts | 3 +- packages/client/lib/commands/ZCOUNT.ts | 16 +- packages/client/lib/commands/ZDIFF.spec.ts | 5 +- packages/client/lib/commands/ZDIFF.ts | 9 +- .../client/lib/commands/ZDIFFSTORE.spec.ts | 5 +- packages/client/lib/commands/ZDIFFSTORE.ts | 13 +- .../lib/commands/ZDIFF_WITHSCORES.spec.ts | 5 +- .../client/lib/commands/ZDIFF_WITHSCORES.ts | 12 +- packages/client/lib/commands/ZINCRBY.spec.ts | 3 +- packages/client/lib/commands/ZINCRBY.ts | 14 +- packages/client/lib/commands/ZINTER.spec.ts | 11 +- packages/client/lib/commands/ZINTER.ts | 24 +- .../client/lib/commands/ZINTERCARD.spec.ts | 7 +- packages/client/lib/commands/ZINTERCARD.ts | 16 +- .../client/lib/commands/ZINTERSTORE.spec.ts | 11 +- packages/client/lib/commands/ZINTERSTORE.ts | 11 +- .../lib/commands/ZINTER_WITHSCORES.spec.ts | 11 +- .../client/lib/commands/ZINTER_WITHSCORES.ts | 11 +- .../client/lib/commands/ZLEXCOUNT.spec.ts | 3 +- packages/client/lib/commands/ZLEXCOUNT.ts | 16 +- packages/client/lib/commands/ZMPOP.spec.ts | 5 +- packages/client/lib/commands/ZMPOP.ts | 30 +- packages/client/lib/commands/ZMSCORE.spec.ts | 5 +- packages/client/lib/commands/ZMSCORE.ts | 14 +- packages/client/lib/commands/ZPOPMAX.spec.ts | 3 +- packages/client/lib/commands/ZPOPMAX.ts | 7 +- .../client/lib/commands/ZPOPMAX_COUNT.spec.ts | 3 +- packages/client/lib/commands/ZPOPMAX_COUNT.ts | 8 +- packages/client/lib/commands/ZPOPMIN.spec.ts | 3 +- packages/client/lib/commands/ZPOPMIN.ts | 7 +- .../client/lib/commands/ZPOPMIN_COUNT.spec.ts | 3 +- packages/client/lib/commands/ZPOPMIN_COUNT.ts | 8 +- .../client/lib/commands/ZRANDMEMBER.spec.ts | 3 +- packages/client/lib/commands/ZRANDMEMBER.ts | 7 +- .../lib/commands/ZRANDMEMBER_COUNT.spec.ts | 3 +- .../client/lib/commands/ZRANDMEMBER_COUNT.ts | 9 +- .../ZRANDMEMBER_COUNT_WITHSCORES.spec.ts | 3 +- .../commands/ZRANDMEMBER_COUNT_WITHSCORES.ts | 11 +- packages/client/lib/commands/ZRANGE.spec.ts | 13 +- packages/client/lib/commands/ZRANGE.ts | 74 +- .../client/lib/commands/ZRANGEBYLEX.spec.ts | 5 +- packages/client/lib/commands/ZRANGEBYLEX.ts | 18 +- .../client/lib/commands/ZRANGEBYSCORE.spec.ts | 5 +- packages/client/lib/commands/ZRANGEBYSCORE.ts | 18 +- .../commands/ZRANGEBYSCORE_WITHSCORES.spec.ts | 5 +- .../lib/commands/ZRANGEBYSCORE_WITHSCORES.ts | 13 +- .../client/lib/commands/ZRANGESTORE.spec.ts | 13 +- packages/client/lib/commands/ZRANGESTORE.ts | 27 +- .../lib/commands/ZRANGE_WITHSCORES.spec.ts | 11 +- .../client/lib/commands/ZRANGE_WITHSCORES.ts | 13 +- packages/client/lib/commands/ZRANK.spec.ts | 3 +- packages/client/lib/commands/ZRANK.ts | 9 +- .../lib/commands/ZRANK_WITHSCORE.spec.ts | 3 +- .../client/lib/commands/ZRANK_WITHSCORE.ts | 11 +- packages/client/lib/commands/ZREM.spec.ts | 5 +- packages/client/lib/commands/ZREM.ts | 11 +- .../lib/commands/ZREMRANGEBYLEX.spec.ts | 3 +- .../client/lib/commands/ZREMRANGEBYLEX.ts | 13 +- .../lib/commands/ZREMRANGEBYRANK.spec.ts | 3 +- .../client/lib/commands/ZREMRANGEBYRANK.ts | 15 +- .../lib/commands/ZREMRANGEBYSCORE.spec.ts | 3 +- .../client/lib/commands/ZREMRANGEBYSCORE.ts | 13 +- packages/client/lib/commands/ZREVRANK.spec.ts | 3 +- packages/client/lib/commands/ZREVRANK.ts | 9 +- packages/client/lib/commands/ZSCAN.spec.ts | 9 +- packages/client/lib/commands/ZSCAN.ts | 11 +- packages/client/lib/commands/ZSCORE.spec.ts | 3 +- packages/client/lib/commands/ZSCORE.ts | 9 +- packages/client/lib/commands/ZUNION.spec.ts | 11 +- packages/client/lib/commands/ZUNION.ts | 16 +- .../client/lib/commands/ZUNIONSTORE.spec.ts | 11 +- packages/client/lib/commands/ZUNIONSTORE.ts | 19 +- .../lib/commands/ZUNION_WITHSCORES.spec.ts | 11 +- .../client/lib/commands/ZUNION_WITHSCORES.ts | 13 +- .../lib/commands/generic-transformers.ts | 93 +- packages/client/lib/multi-command.ts | 10 +- .../lib/sentinel/commands/SENTINEL_MASTER.ts | 5 +- .../lib/sentinel/commands/SENTINEL_MONITOR.ts | 5 +- .../sentinel/commands/SENTINEL_REPLICAS.ts | 5 +- .../sentinel/commands/SENTINEL_SENTINELS.ts | 5 +- .../lib/sentinel/commands/SENTINEL_SET.ts | 9 +- packages/client/lib/sentinel/index.spec.ts | 13 +- packages/client/lib/sentinel/index.ts | 26 +- .../client/lib/sentinel/multi-commands.ts | 107 +- packages/client/lib/sentinel/utils.ts | 70 +- packages/client/lib/test-utils.ts | 8 + .../graph/lib/commands/CONFIG_GET.spec.ts | 3 +- packages/graph/lib/commands/CONFIG_GET.ts | 9 +- .../graph/lib/commands/CONFIG_SET.spec.ts | 3 +- packages/graph/lib/commands/CONFIG_SET.ts | 14 +- packages/graph/lib/commands/DELETE.spec.ts | 3 +- packages/graph/lib/commands/DELETE.ts | 9 +- packages/graph/lib/commands/EXPLAIN.spec.ts | 3 +- packages/graph/lib/commands/EXPLAIN.ts | 10 +- packages/graph/lib/commands/LIST.spec.ts | 3 +- packages/graph/lib/commands/LIST.ts | 9 +- packages/graph/lib/commands/PROFILE.spec.ts | 3 +- packages/graph/lib/commands/PROFILE.ts | 10 +- packages/graph/lib/commands/QUERY.spec.ts | 11 +- packages/graph/lib/commands/QUERY.ts | 28 +- packages/graph/lib/commands/RO_QUERY.spec.ts | 3 +- packages/graph/lib/commands/RO_QUERY.ts | 7 +- packages/graph/lib/commands/SLOWLOG.spec.ts | 3 +- packages/graph/lib/commands/SLOWLOG.ts | 9 +- packages/graph/lib/commands/index.ts | 2 +- packages/graph/lib/graph.ts | 2 +- packages/json/lib/commands/ARRAPPEND.spec.ts | 5 +- packages/json/lib/commands/ARRAPPEND.ts | 20 +- packages/json/lib/commands/ARRINDEX.spec.ts | 7 +- packages/json/lib/commands/ARRINDEX.ts | 17 +- packages/json/lib/commands/ARRINSERT.spec.ts | 5 +- packages/json/lib/commands/ARRINSERT.ts | 21 +- packages/json/lib/commands/ARRLEN.spec.ts | 5 +- packages/json/lib/commands/ARRLEN.ts | 14 +- packages/json/lib/commands/ARRPOP.spec.ts | 7 +- packages/json/lib/commands/ARRPOP.ts | 17 +- packages/json/lib/commands/ARRTRIM.spec.ts | 3 +- packages/json/lib/commands/ARRTRIM.ts | 10 +- packages/json/lib/commands/CLEAR.spec.ts | 5 +- packages/json/lib/commands/CLEAR.ts | 13 +- .../json/lib/commands/DEBUG_MEMORY.spec.ts | 5 +- packages/json/lib/commands/DEBUG_MEMORY.ts | 13 +- packages/json/lib/commands/DEL.spec.ts | 5 +- packages/json/lib/commands/DEL.ts | 13 +- packages/json/lib/commands/FORGET.spec.ts | 5 +- packages/json/lib/commands/FORGET.ts | 13 +- packages/json/lib/commands/GET.spec.ts | 7 +- packages/json/lib/commands/GET.ts | 16 +- packages/json/lib/commands/MERGE.spec.ts | 3 +- packages/json/lib/commands/MERGE.ts | 15 +- packages/json/lib/commands/MGET.spec.ts | 3 +- packages/json/lib/commands/MGET.ts | 14 +- packages/json/lib/commands/MSET.spec.ts | 3 +- packages/json/lib/commands/MSET.ts | 18 +- packages/json/lib/commands/NUMINCRBY.spec.ts | 3 +- packages/json/lib/commands/NUMINCRBY.ts | 10 +- packages/json/lib/commands/NUMMULTBY.spec.ts | 3 +- packages/json/lib/commands/NUMMULTBY.ts | 10 +- packages/json/lib/commands/OBJKEYS.spec.ts | 5 +- packages/json/lib/commands/OBJKEYS.ts | 14 +- packages/json/lib/commands/OBJLEN.spec.ts | 5 +- packages/json/lib/commands/OBJLEN.ts | 14 +- packages/json/lib/commands/RESP.spec.ts | 7 +- packages/json/lib/commands/RESP.ts | 25 +- packages/json/lib/commands/SET.spec.ts | 7 +- packages/json/lib/commands/SET.ts | 19 +- packages/json/lib/commands/STRAPPEND.spec.ts | 5 +- packages/json/lib/commands/STRAPPEND.ts | 14 +- packages/json/lib/commands/STRLEN.spec.ts | 5 +- packages/json/lib/commands/STRLEN.ts | 13 +- packages/json/lib/commands/TOGGLE.spec.ts | 3 +- packages/json/lib/commands/TOGGLE.ts | 10 +- packages/json/lib/commands/TYPE.spec.ts | 5 +- packages/json/lib/commands/TYPE.ts | 14 +- packages/json/lib/commands/index.ts | 4 +- .../search/lib/commands/AGGREGATE.spec.ts | 70 +- packages/search/lib/commands/AGGREGATE.ts | 73 +- .../lib/commands/AGGREGATE_WITHCURSOR.spec.ts | 7 +- .../lib/commands/AGGREGATE_WITHCURSOR.ts | 17 +- packages/search/lib/commands/ALIASADD.spec.ts | 3 +- packages/search/lib/commands/ALIASADD.ts | 9 +- packages/search/lib/commands/ALIASDEL.spec.ts | 3 +- packages/search/lib/commands/ALIASDEL.ts | 9 +- .../search/lib/commands/ALIASUPDATE.spec.ts | 3 +- packages/search/lib/commands/ALIASUPDATE.ts | 9 +- packages/search/lib/commands/ALTER.spec.ts | 3 +- packages/search/lib/commands/ALTER.ts | 14 +- .../search/lib/commands/CONFIG_GET.spec.ts | 3 +- packages/search/lib/commands/CONFIG_GET.ts | 9 +- .../search/lib/commands/CONFIG_SET.spec.ts | 3 +- packages/search/lib/commands/CONFIG_SET.ts | 9 +- packages/search/lib/commands/CREATE.spec.ts | 83 +- packages/search/lib/commands/CREATE.ts | 103 +- .../search/lib/commands/CURSOR_DEL.spec.ts | 3 +- packages/search/lib/commands/CURSOR_DEL.ts | 9 +- .../search/lib/commands/CURSOR_READ.spec.ts | 5 +- packages/search/lib/commands/CURSOR_READ.ts | 13 +- packages/search/lib/commands/DICTADD.spec.ts | 5 +- packages/search/lib/commands/DICTADD.ts | 12 +- packages/search/lib/commands/DICTDEL.spec.ts | 5 +- packages/search/lib/commands/DICTDEL.ts | 12 +- packages/search/lib/commands/DICTDUMP.spec.ts | 3 +- packages/search/lib/commands/DICTDUMP.ts | 9 +- .../search/lib/commands/DROPINDEX.spec.ts | 5 +- packages/search/lib/commands/DROPINDEX.ts | 13 +- packages/search/lib/commands/EXPLAIN.spec.ts | 7 +- packages/search/lib/commands/EXPLAIN.ts | 18 +- .../search/lib/commands/EXPLAINCLI.spec.ts | 3 +- packages/search/lib/commands/EXPLAINCLI.ts | 9 +- packages/search/lib/commands/INFO.spec.ts | 3 +- packages/search/lib/commands/INFO.ts | 11 +- .../lib/commands/PROFILE_AGGREGATE.spec.ts | 5 +- .../search/lib/commands/PROFILE_AGGREGATE.ts | 21 +- .../lib/commands/PROFILE_SEARCH.spec.ts | 5 +- .../search/lib/commands/PROFILE_SEARCH.ts | 22 +- packages/search/lib/commands/SEARCH.spec.ts | 53 +- packages/search/lib/commands/SEARCH.ts | 77 +- .../lib/commands/SEARCH_NOCONTENT.spec.ts | 3 +- .../search/lib/commands/SEARCH_NOCONTENT.ts | 11 +- .../search/lib/commands/SPELLCHECK.spec.ts | 11 +- packages/search/lib/commands/SPELLCHECK.ts | 27 +- packages/search/lib/commands/SUGADD.spec.ts | 7 +- packages/search/lib/commands/SUGADD.ts | 16 +- packages/search/lib/commands/SUGDEL.spec.ts | 3 +- packages/search/lib/commands/SUGDEL.ts | 10 +- packages/search/lib/commands/SUGGET.spec.ts | 7 +- packages/search/lib/commands/SUGGET.ts | 16 +- .../lib/commands/SUGGET_WITHPAYLOADS.spec.ts | 3 +- .../lib/commands/SUGGET_WITHPAYLOADS.ts | 12 +- .../lib/commands/SUGGET_WITHSCORES.spec.ts | 3 +- .../search/lib/commands/SUGGET_WITHSCORES.ts | 12 +- .../SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts | 3 +- .../SUGGET_WITHSCORES_WITHPAYLOADS.ts | 12 +- packages/search/lib/commands/SUGLEN.spec.ts | 3 +- packages/search/lib/commands/SUGLEN.ts | 8 +- packages/search/lib/commands/SYNDUMP.spec.ts | 3 +- packages/search/lib/commands/SYNDUMP.ts | 9 +- .../search/lib/commands/SYNUPDATE.spec.ts | 7 +- packages/search/lib/commands/SYNUPDATE.ts | 16 +- packages/search/lib/commands/TAGVALS.spec.ts | 3 +- packages/search/lib/commands/TAGVALS.ts | 9 +- packages/search/lib/commands/_LIST.spec.ts | 3 +- packages/search/lib/commands/_LIST.ts | 9 +- packages/test-utils/lib/dockers.ts | 2 +- packages/time-series/lib/commands/ADD.spec.ts | 17 +- packages/time-series/lib/commands/ADD.ts | 40 +- .../time-series/lib/commands/ALTER.spec.ts | 15 +- packages/time-series/lib/commands/ALTER.ts | 25 +- .../time-series/lib/commands/CREATE.spec.ts | 17 +- packages/time-series/lib/commands/CREATE.ts | 35 +- .../lib/commands/CREATERULE.spec.ts | 5 +- .../time-series/lib/commands/CREATERULE.ts | 22 +- .../time-series/lib/commands/DECRBY.spec.ts | 17 +- packages/time-series/lib/commands/DECRBY.ts | 12 +- packages/time-series/lib/commands/DEL.spec.ts | 3 +- packages/time-series/lib/commands/DEL.ts | 15 +- .../lib/commands/DELETERULE.spec.ts | 3 +- .../time-series/lib/commands/DELETERULE.ts | 13 +- packages/time-series/lib/commands/GET.spec.ts | 5 +- packages/time-series/lib/commands/GET.ts | 13 +- .../time-series/lib/commands/INCRBY.spec.ts | 19 +- packages/time-series/lib/commands/INCRBY.ts | 38 +- .../time-series/lib/commands/INFO.spec.ts | 3 +- packages/time-series/lib/commands/INFO.ts | 9 +- .../lib/commands/INFO_DEBUG.spec.ts | 3 +- .../time-series/lib/commands/INFO_DEBUG.ts | 14 +- .../time-series/lib/commands/MADD.spec.ts | 3 +- packages/time-series/lib/commands/MADD.ts | 17 +- .../time-series/lib/commands/MGET.spec.ts | 5 +- packages/time-series/lib/commands/MGET.ts | 26 +- .../lib/commands/MGET_SELECTED_LABELS.spec.ts | 3 +- .../lib/commands/MGET_SELECTED_LABELS.ts | 19 +- .../lib/commands/MGET_WITHLABELS.spec.ts | 3 +- .../lib/commands/MGET_WITHLABELS.ts | 17 +- .../time-series/lib/commands/MRANGE.spec.ts | 3 +- packages/time-series/lib/commands/MRANGE.ts | 21 +- .../lib/commands/MRANGE_GROUPBY.spec.ts | 3 +- .../lib/commands/MRANGE_GROUPBY.ts | 33 +- .../commands/MRANGE_SELECTED_LABELS.spec.ts | 3 +- .../lib/commands/MRANGE_SELECTED_LABELS.ts | 24 +- .../MRANGE_SELECTED_LABELS_GROUPBY.spec.ts | 3 +- .../MRANGE_SELECTED_LABELS_GROUPBY.ts | 30 +- .../lib/commands/MRANGE_WITHLABELS.spec.ts | 3 +- .../lib/commands/MRANGE_WITHLABELS.ts | 23 +- .../MRANGE_WITHLABELS_GROUPBY.spec.ts | 3 +- .../lib/commands/MRANGE_WITHLABELS_GROUPBY.ts | 30 +- .../lib/commands/MREVRANGE.spec.ts | 3 +- .../time-series/lib/commands/MREVRANGE.ts | 6 +- .../lib/commands/MREVRANGE_GROUPBY.spec.ts | 3 +- .../lib/commands/MREVRANGE_GROUPBY.ts | 5 +- .../MREVRANGE_SELECTED_LABELS.spec.ts | 3 +- .../lib/commands/MREVRANGE_SELECTED_LABELS.ts | 5 +- .../MREVRANGE_SELECTED_LABELS_GROUPBY.spec.ts | 3 +- .../MREVRANGE_SELECTED_LABELS_GROUPBY.ts | 5 +- .../lib/commands/MREVRANGE_WITHLABELS.spec.ts | 3 +- .../lib/commands/MREVRANGE_WITHLABELS.ts | 6 +- .../MREVRANGE_WITHLABELS_GROUPBY.spec.ts | 3 +- .../commands/MREVRANGE_WITHLABELS_GROUPBY.ts | 5 +- .../lib/commands/QUERYINDEX.spec.ts | 5 +- .../time-series/lib/commands/QUERYINDEX.ts | 12 +- .../time-series/lib/commands/RANGE.spec.ts | 3 +- packages/time-series/lib/commands/RANGE.ts | 49 +- .../time-series/lib/commands/REVRANGE.spec.ts | 3 +- packages/time-series/lib/commands/REVRANGE.ts | 10 +- .../time-series/lib/commands/index.spec.ts | 2 +- packages/time-series/lib/commands/index.ts | 41 +- 1016 files changed, 6345 insertions(+), 6540 deletions(-) create mode 100644 packages/client/lib/client/parser.ts diff --git a/package-lock.json b/package-lock.json index aefd067843..ba18a98b6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,9 +23,8 @@ }, "node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -36,9 +35,8 @@ }, "node_modules/@babel/code-frame": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -49,9 +47,8 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -61,9 +58,8 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -75,42 +71,37 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -120,18 +111,16 @@ }, "node_modules/@babel/compat-data": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -159,15 +148,13 @@ }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/generator": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", @@ -180,9 +167,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-validator-option": "^7.23.5", @@ -196,18 +182,16 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -218,9 +202,8 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -230,9 +213,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.15" }, @@ -242,9 +224,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -261,9 +242,8 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -273,9 +253,8 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -285,36 +264,32 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.23.9", "@babel/traverse": "^7.23.9", @@ -326,9 +301,8 @@ }, "node_modules/@babel/highlight": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -340,9 +314,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -352,9 +325,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -366,42 +338,37 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -411,9 +378,8 @@ }, "node_modules/@babel/parser": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -423,9 +389,8 @@ }, "node_modules/@babel/template": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/parser": "^7.23.9", @@ -437,9 +402,8 @@ }, "node_modules/@babel/traverse": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", @@ -458,9 +422,8 @@ }, "node_modules/@babel/types": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -470,270 +433,13 @@ "node": ">=6.9.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/linux-x64": { "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -742,113 +448,15 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@iarna/toml": { "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -862,18 +470,16 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -884,9 +490,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -897,9 +502,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -909,9 +513,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -924,9 +527,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -936,9 +538,8 @@ }, "node_modules/@istanbuljs/nyc-config-typescript": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", - "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2" }, @@ -951,18 +552,16 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -974,33 +573,29 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1008,9 +603,8 @@ }, "node_modules/@ljharb/through": { "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5" }, @@ -1020,9 +614,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1033,18 +626,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1055,18 +646,16 @@ }, "node_modules/@octokit/auth-token": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@octokit/core": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz", - "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.0.0", @@ -1082,9 +671,8 @@ }, "node_modules/@octokit/endpoint": { "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", - "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^12.0.0", "universal-user-agent": "^6.0.0" @@ -1095,9 +683,8 @@ }, "node_modules/@octokit/graphql": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/request": "^8.0.1", "@octokit/types": "^12.0.0", @@ -1109,15 +696,13 @@ }, "node_modules/@octokit/openapi-types": { "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", - "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", - "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^12.4.0" }, @@ -1130,9 +715,8 @@ }, "node_modules/@octokit/plugin-request-log": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", - "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 18" }, @@ -1142,9 +726,8 @@ }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", - "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^12.3.0" }, @@ -1157,9 +740,8 @@ }, "node_modules/@octokit/request": { "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/endpoint": "^9.0.0", "@octokit/request-error": "^5.0.0", @@ -1172,9 +754,8 @@ }, "node_modules/@octokit/request-error": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^12.0.0", "deprecation": "^2.0.0", @@ -1186,9 +767,8 @@ }, "node_modules/@octokit/rest": { "version": "20.0.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", - "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/core": "^5.0.0", "@octokit/plugin-paginate-rest": "^9.0.0", @@ -1201,27 +781,24 @@ }, "node_modules/@octokit/types": { "version": "12.4.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", - "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/openapi-types": "^19.1.0" } }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.22.0" } }, "node_modules/@pnpm/network.ca-file": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "4.2.10" }, @@ -1231,15 +808,13 @@ }, "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@pnpm/npm-conf": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", "dev": true, + "license": "MIT", "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", @@ -1279,9 +854,8 @@ }, "node_modules/@sindresorhus/is": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -1291,9 +865,8 @@ }, "node_modules/@sindresorhus/merge-streams": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -1303,27 +876,24 @@ }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "node_modules/@sinonjs/samsam": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", @@ -1332,24 +902,21 @@ }, "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, + "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.1" }, @@ -1359,66 +926,57 @@ }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mocha": { "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "20.11.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", - "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/sinon": { "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, + "license": "MIT", "dependencies": { "@types/sinonjs__fake-timers": "*" } }, "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", - "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/agent-base": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -1428,9 +986,8 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -1441,27 +998,24 @@ }, "node_modules/ansi-align": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.1.0" } }, "node_modules/ansi-colors": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1474,9 +1028,8 @@ }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -1486,24 +1039,21 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-sequence-parser": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1516,9 +1066,8 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1529,9 +1078,8 @@ }, "node_modules/append-transform": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, + "license": "MIT", "dependencies": { "default-require-extensions": "^3.0.0" }, @@ -1541,21 +1089,18 @@ }, "node_modules/archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -1569,9 +1114,8 @@ }, "node_modules/array-union": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, + "license": "MIT", "dependencies": { "array-uniq": "^1.0.1" }, @@ -1581,18 +1125,16 @@ }, "node_modules/array-uniq": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/array.prototype.map": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.6.tgz", - "integrity": "sha512-nK1psgF2cXqP3wSyCSq0Hc7zwNq3sfljQqaG27r/7a7ooNUnn5nGq6yYWyks9jMO5EoFQ0ax80hSg6oXSRNXaw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -1609,9 +1151,8 @@ }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -1631,9 +1172,8 @@ }, "node_modules/ast-types": { "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -1643,24 +1183,21 @@ }, "node_modules/async": { "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/async-retry": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", "dev": true, + "license": "MIT", "dependencies": { "retry": "0.13.1" } }, "node_modules/available-typed-arrays": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1670,14 +1207,11 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { @@ -1692,37 +1226,34 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/basic-ftp": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/before-after-hook": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -1731,9 +1262,8 @@ }, "node_modules/boxen": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", "dev": true, + "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.1", @@ -1753,9 +1283,8 @@ }, "node_modules/boxen/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1765,9 +1294,8 @@ }, "node_modules/boxen/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1777,9 +1305,8 @@ }, "node_modules/boxen/node_modules/camelcase": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -1789,9 +1316,8 @@ }, "node_modules/boxen/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -1801,15 +1327,13 @@ }, "node_modules/boxen/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/boxen/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1824,9 +1348,8 @@ }, "node_modules/boxen/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1839,9 +1362,8 @@ }, "node_modules/boxen/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -1851,9 +1373,8 @@ }, "node_modules/boxen/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -1868,9 +1389,8 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1878,9 +1398,8 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -1890,14 +1409,11 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/browserslist": { "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", "dev": true, "funding": [ { @@ -1913,6 +1429,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001580", "electron-to-chromium": "^1.4.648", @@ -1928,8 +1445,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -1945,6 +1460,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -1952,9 +1468,8 @@ }, "node_modules/bundle-name": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "dev": true, + "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" }, @@ -1967,18 +1482,16 @@ }, "node_modules/cacheable-lookup": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" } }, "node_modules/cacheable-request": { "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", @@ -1994,9 +1507,8 @@ }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2006,9 +1518,8 @@ }, "node_modules/caching-transform": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, + "license": "MIT", "dependencies": { "hasha": "^5.0.0", "make-dir": "^3.0.0", @@ -2021,9 +1532,8 @@ }, "node_modules/call-bind": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -2035,26 +1545,22 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { "version": "1.0.30001584", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz", - "integrity": "sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==", "dev": true, "funding": [ { @@ -2069,13 +1575,13 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2089,9 +1595,8 @@ }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2101,14 +1606,11 @@ }, "node_modules/chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/chokidar": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -2116,6 +1618,7 @@ "url": "https://paulmillr.com/funding/" } ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2134,8 +1637,6 @@ }, "node_modules/ci-info": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -2143,24 +1644,23 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-boxes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2170,9 +1670,8 @@ }, "node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -2182,9 +1681,8 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -2194,18 +1692,16 @@ }, "node_modules/cli-width": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, + "license": "ISC", "engines": { "node": ">= 12" } }, "node_modules/cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -2214,9 +1710,8 @@ }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2231,26 +1726,23 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2260,36 +1752,31 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" } }, "node_modules/commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/config-chain": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, + "license": "MIT", "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" @@ -2297,15 +1784,13 @@ }, "node_modules/config-chain/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/configstore": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dot-prop": "^6.0.1", "graceful-fs": "^4.2.6", @@ -2322,15 +1807,13 @@ }, "node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -2354,9 +1837,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2368,9 +1850,8 @@ }, "node_modules/crypto-random-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^1.0.1" }, @@ -2383,9 +1864,8 @@ }, "node_modules/crypto-random-string/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2395,18 +1875,16 @@ }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -2421,24 +1899,21 @@ }, "node_modules/debug/node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -2451,9 +1926,8 @@ }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2463,18 +1937,16 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/default-browser": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dev": true, + "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" @@ -2488,9 +1960,8 @@ }, "node_modules/default-browser-id": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -2500,9 +1971,8 @@ }, "node_modules/default-require-extensions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, + "license": "MIT", "dependencies": { "strip-bom": "^4.0.0" }, @@ -2515,9 +1985,8 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -2527,18 +1996,16 @@ }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/define-data-property": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -2550,9 +2017,8 @@ }, "node_modules/define-lazy-prop": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2562,9 +2028,8 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -2579,9 +2044,8 @@ }, "node_modules/degenerator": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -2593,24 +2057,21 @@ }, "node_modules/deprecation": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/diff": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dot-prop": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "dev": true, + "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, @@ -2623,51 +2084,44 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.4.656", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.656.tgz", - "integrity": "sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/email-addresses": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/env-paths": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -2718,24 +2172,21 @@ }, "node_modules/es-array-method-boxes-properly": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-get-iterator": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -2753,9 +2204,8 @@ }, "node_modules/es-set-tostringtag": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -2767,9 +2217,8 @@ }, "node_modules/es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -2784,16 +2233,14 @@ }, "node_modules/es6-error": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esbuild": { "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -2828,18 +2275,16 @@ }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-goat": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2849,9 +2294,8 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2861,9 +2305,8 @@ }, "node_modules/escodegen": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -2882,9 +2325,8 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2895,27 +2337,24 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/execa": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -2936,9 +2375,8 @@ }, "node_modules/execa/node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -2948,9 +2386,8 @@ }, "node_modules/execa/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -2960,9 +2397,8 @@ }, "node_modules/external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -2974,9 +2410,8 @@ }, "node_modules/fast-glob": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2990,17 +2425,14 @@ }, "node_modules/fastq": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fetch-blob": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "dev": true, "funding": [ { @@ -3012,6 +2444,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -3022,9 +2455,8 @@ }, "node_modules/figures": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0", "is-unicode-supported": "^1.2.0" @@ -3038,9 +2470,8 @@ }, "node_modules/figures/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -3050,9 +2481,8 @@ }, "node_modules/figures/node_modules/is-unicode-supported": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -3062,18 +2492,16 @@ }, "node_modules/filename-reserved-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/filenamify": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, + "license": "MIT", "dependencies": { "filename-reserved-regex": "^2.0.0", "strip-outer": "^1.0.1", @@ -3088,9 +2516,8 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3100,9 +2527,8 @@ }, "node_modules/find-cache-dir": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -3117,9 +2543,8 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -3133,27 +2558,24 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/foreground-child": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" @@ -3164,18 +2586,16 @@ }, "node_modules/form-data-encoder": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14.17" } }, "node_modules/formdata-polyfill": { "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dev": true, + "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" }, @@ -3185,8 +2605,6 @@ }, "node_modules/fromentries": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true, "funding": [ { @@ -3201,13 +2619,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -3219,38 +2637,21 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3266,36 +2667,32 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3305,9 +2702,8 @@ }, "node_modules/get-intrinsic": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.3.tgz", - "integrity": "sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.0.0", "function-bind": "^1.1.2", @@ -3324,18 +2720,16 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/get-stream": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -3345,9 +2739,8 @@ }, "node_modules/get-symbol-description": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -3361,9 +2754,8 @@ }, "node_modules/get-tsconfig": { "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -3373,9 +2765,8 @@ }, "node_modules/get-uri": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", "dev": true, + "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.0", @@ -3388,18 +2779,16 @@ }, "node_modules/get-uri/node_modules/data-uri-to-buffer": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/get-uri/node_modules/fs-extra": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -3411,27 +2800,24 @@ }, "node_modules/get-uri/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/get-uri/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/gh-pages": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz", - "integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==", "dev": true, + "license": "MIT", "dependencies": { "async": "^3.2.4", "commander": "^11.0.0", @@ -3451,9 +2837,8 @@ }, "node_modules/git-up": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "dev": true, + "license": "MIT", "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" @@ -3461,18 +2846,16 @@ }, "node_modules/git-url-parse": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.0.0.tgz", - "integrity": "sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==", "dev": true, + "license": "MIT", "dependencies": { "git-up": "^7.0.0" } }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3490,9 +2873,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3502,9 +2884,8 @@ }, "node_modules/global-dirs": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "dev": true, + "license": "MIT", "dependencies": { "ini": "2.0.0" }, @@ -3517,18 +2898,16 @@ }, "node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globalthis": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -3541,9 +2920,8 @@ }, "node_modules/globby": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^1.0.1", "glob": "^7.0.3", @@ -3557,9 +2935,8 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3569,9 +2946,8 @@ }, "node_modules/got": { "version": "13.0.0", - "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz", - "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -3594,9 +2970,8 @@ }, "node_modules/got/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3606,33 +2981,29 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -3642,9 +3013,8 @@ }, "node_modules/has-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3654,9 +3024,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3666,9 +3035,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -3681,9 +3049,8 @@ }, "node_modules/hasha": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, + "license": "MIT", "dependencies": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" @@ -3697,9 +3064,8 @@ }, "node_modules/hasown": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -3709,30 +3075,26 @@ }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, + "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-cache-semantics": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -3743,9 +3105,8 @@ }, "node_modules/http2-wrapper": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, + "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -3756,9 +3117,8 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -3769,18 +3129,16 @@ }, "node_modules/human-signals": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -3790,8 +3148,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { @@ -3806,22 +3162,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3835,45 +3190,40 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3881,24 +3231,21 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ini": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/inquirer": { "version": "9.2.12", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.12.tgz", - "integrity": "sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==", "dev": true, + "license": "MIT", "dependencies": { "@ljharb/through": "^2.3.11", "ansi-escapes": "^4.3.2", @@ -3922,9 +3269,8 @@ }, "node_modules/inquirer/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -3934,18 +3280,16 @@ }, "node_modules/inquirer/node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -3966,9 +3310,8 @@ }, "node_modules/inquirer/node_modules/ora/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3982,9 +3325,8 @@ }, "node_modules/inquirer/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3994,9 +3336,8 @@ }, "node_modules/internal-slot": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2", "hasown": "^2.0.0", @@ -4008,24 +3349,21 @@ }, "node_modules/interpret": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/ip": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-arguments": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4039,9 +3377,8 @@ }, "node_modules/is-array-buffer": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -4055,15 +3392,13 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -4073,9 +3408,8 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -4085,9 +3419,8 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4101,9 +3434,8 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4113,9 +3445,8 @@ }, "node_modules/is-ci": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, + "license": "MIT", "dependencies": { "ci-info": "^3.2.0" }, @@ -4125,9 +3456,8 @@ }, "node_modules/is-core-module": { "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -4137,9 +3467,8 @@ }, "node_modules/is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4152,9 +3481,8 @@ }, "node_modules/is-docker": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -4167,27 +3495,24 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -4197,9 +3522,8 @@ }, "node_modules/is-in-ci": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-0.1.0.tgz", - "integrity": "sha512-d9PXLEY0v1iJ64xLiQMJ51J128EYHAaOR4yZqQi8aHGfw6KgifM3/Viw1oZZ1GCVmb3gBuyhLyHj0HgR2DhSXQ==", "dev": true, + "license": "MIT", "bin": { "is-in-ci": "cli.js" }, @@ -4212,9 +3536,8 @@ }, "node_modules/is-inside-container": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^3.0.0" }, @@ -4230,9 +3553,8 @@ }, "node_modules/is-installed-globally": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, + "license": "MIT", "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -4246,9 +3568,8 @@ }, "node_modules/is-interactive": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4258,18 +3579,16 @@ }, "node_modules/is-map": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4279,9 +3598,8 @@ }, "node_modules/is-npm": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4291,18 +3609,16 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4315,36 +3631,32 @@ }, "node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4358,18 +3670,16 @@ }, "node_modules/is-set": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -4379,18 +3689,16 @@ }, "node_modules/is-ssh": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", "dev": true, + "license": "MIT", "dependencies": { "protocols": "^2.0.1" } }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4400,9 +3708,8 @@ }, "node_modules/is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4415,9 +3722,8 @@ }, "node_modules/is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -4430,9 +3736,8 @@ }, "node_modules/is-typed-array": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -4445,15 +3750,13 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4463,9 +3766,8 @@ }, "node_modules/is-weakref": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -4475,18 +3777,16 @@ }, "node_modules/is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-wsl": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, + "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" }, @@ -4499,21 +3799,18 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/issue-parser": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", "dev": true, + "license": "MIT", "dependencies": { "lodash.capitalize": "^4.2.1", "lodash.escaperegexp": "^4.1.2", @@ -4527,18 +3824,16 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-hook": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "append-transform": "^2.0.0" }, @@ -4548,9 +3843,8 @@ }, "node_modules/istanbul-lib-instrument": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -4563,9 +3857,8 @@ }, "node_modules/istanbul-lib-processinfo": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, + "license": "ISC", "dependencies": { "archy": "^1.0.0", "cross-spawn": "^7.0.3", @@ -4580,9 +3873,8 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -4594,9 +3886,8 @@ }, "node_modules/istanbul-lib-report/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -4606,9 +3897,8 @@ }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -4621,9 +3911,8 @@ }, "node_modules/istanbul-lib-report/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -4636,9 +3925,8 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4648,15 +3936,13 @@ }, "node_modules/istanbul-lib-report/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -4668,9 +3954,8 @@ }, "node_modules/istanbul-reports": { "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4681,18 +3966,16 @@ }, "node_modules/iterate-iterator": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.2.tgz", - "integrity": "sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/iterate-value": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", "dev": true, + "license": "MIT", "dependencies": { "es-get-iterator": "^1.0.2", "iterate-iterator": "^1.0.1" @@ -4703,15 +3986,13 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4721,9 +4002,8 @@ }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -4733,21 +4013,18 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4757,15 +4034,13 @@ }, "node_modules/jsonc-parser": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -4775,24 +4050,21 @@ }, "node_modules/just-extend": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/latest-version": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", "dev": true, + "license": "MIT", "dependencies": { "package-json": "^8.1.0" }, @@ -4805,15 +4077,13 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -4826,57 +4096,48 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.capitalize": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.flattendeep": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.get": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.uniqby": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -4890,9 +4151,8 @@ }, "node_modules/lowercase-keys": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4902,24 +4162,21 @@ }, "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/lunr": { "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/macos-release": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-3.2.0.tgz", - "integrity": "sha512-fSErXALFNsnowREYZ49XCdOHF8wOPWuFOGQrAhP7x5J/BqQv+B02cNsTykGpDgRVx43EKg++6ANmTaGTtW+hUA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4929,9 +4186,8 @@ }, "node_modules/make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -4944,9 +4200,8 @@ }, "node_modules/marked": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -4956,24 +4211,21 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -4984,18 +4236,16 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -5005,9 +4255,8 @@ }, "node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5017,9 +4266,8 @@ }, "node_modules/mimic-response": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -5029,9 +4277,8 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5041,18 +4288,16 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mocha": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", @@ -5090,9 +4335,8 @@ }, "node_modules/mocha/node_modules/glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5110,9 +4354,8 @@ }, "node_modules/mocha/node_modules/glob/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5122,9 +4365,8 @@ }, "node_modules/mocha/node_modules/minimatch": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5134,33 +4376,29 @@ }, "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mute-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/nanoid": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -5170,18 +4408,16 @@ }, "node_modules/netmask": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/new-github-release-url": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/new-github-release-url/-/new-github-release-url-2.0.0.tgz", - "integrity": "sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.5.1" }, @@ -5194,9 +4430,8 @@ }, "node_modules/new-github-release-url/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -5206,9 +4441,8 @@ }, "node_modules/nise": { "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", "@sinonjs/fake-timers": "^11.2.2", @@ -5219,8 +4453,6 @@ }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "dev": true, "funding": [ { @@ -5232,15 +4464,15 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } }, "node_modules/node-fetch": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -5256,9 +4488,8 @@ }, "node_modules/node-preload": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, + "license": "MIT", "dependencies": { "process-on-spawn": "^1.0.0" }, @@ -5268,24 +4499,21 @@ }, "node_modules/node-releases": { "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -5295,9 +4523,8 @@ }, "node_modules/npm-run-path": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -5310,9 +4537,8 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5322,9 +4548,8 @@ }, "node_modules/nyc": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -5363,9 +4588,8 @@ }, "node_modules/nyc/node_modules/cliui": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -5374,9 +4598,8 @@ }, "node_modules/nyc/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5387,9 +4610,8 @@ }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -5399,9 +4621,8 @@ }, "node_modules/nyc/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -5414,9 +4635,8 @@ }, "node_modules/nyc/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -5426,15 +4646,13 @@ }, "node_modules/nyc/node_modules/y18n": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nyc/node_modules/yargs": { "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -5454,9 +4672,8 @@ }, "node_modules/nyc/node_modules/yargs-parser": { "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -5467,36 +4684,32 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -5512,18 +4725,16 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -5536,9 +4747,8 @@ }, "node_modules/open": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/open/-/open-10.0.3.tgz", - "integrity": "sha512-dtbI5oW7987hwC9qjJTyABldTaa19SuyJse1QboWv3b0qCcrrLNVDqBx1XgELAjh9QTVQaP/C5b1nhQebd1H2A==", "dev": true, + "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", @@ -5554,9 +4764,8 @@ }, "node_modules/ora": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", - "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^4.0.0", @@ -5577,9 +4786,8 @@ }, "node_modules/ora/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5589,9 +4797,8 @@ }, "node_modules/ora/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -5601,9 +4808,8 @@ }, "node_modules/ora/node_modules/cli-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^4.0.0" }, @@ -5616,15 +4822,13 @@ }, "node_modules/ora/node_modules/emoji-regex": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ora/node_modules/is-unicode-supported": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -5634,9 +4838,8 @@ }, "node_modules/ora/node_modules/log-symbols": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" @@ -5650,9 +4853,8 @@ }, "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5662,18 +4864,16 @@ }, "node_modules/ora/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ora/node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -5686,9 +4886,8 @@ }, "node_modules/ora/node_modules/restore-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -5702,9 +4901,8 @@ }, "node_modules/ora/node_modules/string-width": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -5719,9 +4917,8 @@ }, "node_modules/ora/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5734,9 +4931,8 @@ }, "node_modules/os-name": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-5.1.0.tgz", - "integrity": "sha512-YEIoAnM6zFmzw3PQ201gCVCIWbXNyKObGlVvpAVvraAeOHnlYVKFssbA/riRX5R40WA6kKrZ7Dr7dWzO3nKSeQ==", "dev": true, + "license": "MIT", "dependencies": { "macos-release": "^3.1.0", "windows-release": "^5.0.1" @@ -5750,27 +4946,24 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/p-cancelable": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -5783,9 +4976,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -5798,9 +4990,8 @@ }, "node_modules/p-map": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -5810,18 +5001,16 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pac-proxy-agent": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", @@ -5838,9 +5027,8 @@ }, "node_modules/pac-resolver": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", "dev": true, + "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "ip": "^1.1.8", @@ -5852,9 +5040,8 @@ }, "node_modules/package-hash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, + "license": "ISC", "dependencies": { "graceful-fs": "^4.1.15", "hasha": "^5.0.0", @@ -5867,9 +5054,8 @@ }, "node_modules/package-json": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", "dev": true, + "license": "MIT", "dependencies": { "got": "^12.1.0", "registry-auth-token": "^5.0.1", @@ -5885,9 +5071,8 @@ }, "node_modules/package-json/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5897,9 +5082,8 @@ }, "node_modules/package-json/node_modules/got": { "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -5922,9 +5106,8 @@ }, "node_modules/package-json/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -5934,9 +5117,8 @@ }, "node_modules/package-json/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -5949,15 +5131,13 @@ }, "node_modules/package-json/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -5967,9 +5147,8 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -5985,66 +5164,58 @@ }, "node_modules/parse-path": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", "dev": true, + "license": "MIT", "dependencies": { "protocols": "^2.0.0" } }, "node_modules/parse-url": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "dev": true, + "license": "MIT", "dependencies": { "parse-path": "^7.0.0" } }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-to-regexp": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6054,15 +5225,13 @@ }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -6072,27 +5241,24 @@ }, "node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pinkie": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pinkie-promise": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, + "license": "MIT", "dependencies": { "pinkie": "^2.0.0" }, @@ -6102,9 +5268,8 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -6114,9 +5279,8 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -6127,9 +5291,8 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -6139,9 +5302,8 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -6154,9 +5316,8 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -6166,9 +5327,8 @@ }, "node_modules/process-on-spawn": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", "dev": true, + "license": "MIT", "dependencies": { "fromentries": "^1.2.0" }, @@ -6178,9 +5338,8 @@ }, "node_modules/promise.allsettled": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.7.tgz", - "integrity": "sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA==", "dev": true, + "license": "MIT", "dependencies": { "array.prototype.map": "^1.0.5", "call-bind": "^1.0.2", @@ -6198,21 +5357,18 @@ }, "node_modules/proto-list": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/protocols": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/proxy-agent": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -6229,24 +5385,21 @@ }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pupa": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", "dev": true, + "license": "MIT", "dependencies": { "escape-goat": "^4.0.0" }, @@ -6259,8 +5412,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -6275,13 +5426,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6291,18 +5442,16 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -6315,24 +5464,21 @@ }, "node_modules/rc/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6344,9 +5490,8 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -6356,8 +5501,6 @@ }, "node_modules/rechoir": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "dependencies": { "resolve": "^1.1.6" @@ -6372,9 +5515,8 @@ }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6389,9 +5531,8 @@ }, "node_modules/registry-auth-token": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", "dev": true, + "license": "MIT", "dependencies": { "@pnpm/npm-conf": "^2.1.0" }, @@ -6401,9 +5542,8 @@ }, "node_modules/registry-url": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", "dev": true, + "license": "MIT", "dependencies": { "rc": "1.2.8" }, @@ -6416,8 +5556,6 @@ }, "node_modules/release-it": { "version": "17.0.3", - "resolved": "https://registry.npmjs.org/release-it/-/release-it-17.0.3.tgz", - "integrity": "sha512-QjTCmvQm91pwLEbvavEs9jofHNe8thsb9Uimin+8DNSwFRdUd73p0Owy2PP/Dzh/EegRkKq/o+4Pn1xp8pC1og==", "dev": true, "funding": [ { @@ -6429,6 +5567,7 @@ "url": "https://opencollective.com/webpro" } ], + "license": "MIT", "dependencies": { "@iarna/toml": "2.2.5", "@octokit/rest": "20.0.2", @@ -6467,9 +5606,8 @@ }, "node_modules/release-it/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -6479,9 +5617,8 @@ }, "node_modules/release-it/node_modules/globby": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^1.0.0", "fast-glob": "^3.3.2", @@ -6499,9 +5636,8 @@ }, "node_modules/release-it/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6511,9 +5647,8 @@ }, "node_modules/release-it/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6526,24 +5661,21 @@ }, "node_modules/release-it/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/release-it/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/release-zalgo": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, + "license": "ISC", "dependencies": { "es6-error": "^4.0.1" }, @@ -6553,24 +5685,21 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/resolve": { "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -6585,33 +5714,29 @@ }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, "node_modules/responselike": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, + "license": "MIT", "dependencies": { "lowercase-keys": "^3.0.0" }, @@ -6624,9 +5749,8 @@ }, "node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -6637,18 +5761,16 @@ }, "node_modules/restore-cursor/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/restore-cursor/node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -6661,18 +5783,16 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -6680,9 +5800,8 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -6695,9 +5814,8 @@ }, "node_modules/run-applescript": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -6707,17 +5825,14 @@ }, "node_modules/run-async": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -6733,24 +5848,23 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rxjs": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-array-concat": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "get-intrinsic": "^1.2.2", @@ -6766,8 +5880,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -6782,13 +5894,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", - "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "get-intrinsic": "^1.2.2", @@ -6803,24 +5915,21 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/semver-diff": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.3.5" }, @@ -6833,9 +5942,8 @@ }, "node_modules/semver-diff/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6845,9 +5953,8 @@ }, "node_modules/semver-diff/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6860,30 +5967,26 @@ }, "node_modules/semver-diff/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/serialize-javascript": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/set-function-length": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.1", "function-bind": "^1.1.2", @@ -6897,9 +6000,8 @@ }, "node_modules/set-function-name": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -6911,9 +6013,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6923,18 +6024,16 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shelljs": { "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -6949,9 +6048,8 @@ }, "node_modules/shiki": { "version": "0.14.7", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", - "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", @@ -6961,9 +6059,8 @@ }, "node_modules/side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -6975,15 +6072,13 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/sinon": { "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", "@sinonjs/fake-timers": "^11.2.2", @@ -6999,18 +6094,16 @@ }, "node_modules/sinon/node_modules/diff": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/sinon/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7020,9 +6113,8 @@ }, "node_modules/slash": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -7032,9 +6124,8 @@ }, "node_modules/smart-buffer": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -7042,9 +6133,8 @@ }, "node_modules/socks": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, + "license": "MIT", "dependencies": { "ip": "^2.0.0", "smart-buffer": "^4.2.0" @@ -7056,9 +6146,8 @@ }, "node_modules/socks-proxy-agent": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -7070,24 +6159,21 @@ }, "node_modules/socks/node_modules/ip": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/spawn-wrap": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^2.0.0", "is-windows": "^1.0.2", @@ -7102,15 +6188,13 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stdin-discarder": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -7120,9 +6204,8 @@ }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", "dev": true, + "license": "MIT", "dependencies": { "internal-slot": "^1.0.4" }, @@ -7132,18 +6215,16 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7155,9 +6236,8 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7172,9 +6252,8 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7186,9 +6265,8 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7200,9 +6278,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7212,18 +6289,16 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7233,9 +6308,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -7245,9 +6319,8 @@ }, "node_modules/strip-outer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.2" }, @@ -7257,18 +6330,16 @@ }, "node_modules/strip-outer/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7281,9 +6352,8 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7293,9 +6363,8 @@ }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -7307,9 +6376,8 @@ }, "node_modules/tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -7319,18 +6387,16 @@ }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -7340,9 +6406,8 @@ }, "node_modules/trim-repeated": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.2" }, @@ -7352,24 +6417,21 @@ }, "node_modules/trim-repeated/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/tsx": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "~0.19.10", "get-tsconfig": "^4.7.2" @@ -7386,27 +6448,24 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/typed-array-buffer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -7418,9 +6477,8 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -7436,9 +6494,8 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -7455,9 +6512,8 @@ }, "node_modules/typed-array-length": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -7469,18 +6525,16 @@ }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typedoc": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.7.tgz", - "integrity": "sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow==", "dev": true, + "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", "marked": "^4.3.0", @@ -7499,18 +6553,16 @@ }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/typedoc/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7523,9 +6575,8 @@ }, "node_modules/typescript": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7536,9 +6587,8 @@ }, "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -7551,15 +6601,13 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -7569,9 +6617,8 @@ }, "node_modules/unique-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, + "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" }, @@ -7584,23 +6631,19 @@ }, "node_modules/universal-user-agent": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/update-browserslist-db": { "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -7616,6 +6659,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -7629,9 +6673,8 @@ }, "node_modules/update-notifier": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-7.0.0.tgz", - "integrity": "sha512-Hv25Bh+eAbOLlsjJreVPOs4vd51rrtCrmhyOJtbpAojro34jS4KQaEp4/EvlHJX7jSO42VvEFpkastVyXyIsdQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boxen": "^7.1.1", "chalk": "^5.3.0", @@ -7655,9 +6698,8 @@ }, "node_modules/update-notifier/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -7667,9 +6709,8 @@ }, "node_modules/update-notifier/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -7679,9 +6720,8 @@ }, "node_modules/update-notifier/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -7694,69 +6734,60 @@ }, "node_modules/update-notifier/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/url-join": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", - "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/vscode-oniguruma": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/vscode-textmate": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/web-streams-polyfill": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -7769,9 +6800,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -7785,15 +6815,13 @@ }, "node_modules/which-module": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/which-typed-array": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.6", "call-bind": "^1.0.5", @@ -7810,9 +6838,8 @@ }, "node_modules/widest-line": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^5.0.1" }, @@ -7825,9 +6852,8 @@ }, "node_modules/widest-line/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7837,15 +6863,13 @@ }, "node_modules/widest-line/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/widest-line/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -7860,9 +6884,8 @@ }, "node_modules/widest-line/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -7875,15 +6898,13 @@ }, "node_modules/wildcard-match": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/wildcard-match/-/wildcard-match-5.1.2.tgz", - "integrity": "sha512-qNXwI591Z88c8bWxp+yjV60Ch4F8Riawe3iGxbzquhy8Xs9m+0+SLFBGb/0yCTIDElawtaImC37fYZ+dr32KqQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/windows-release": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-5.1.1.tgz", - "integrity": "sha512-NMD00arvqcq2nwqc5Q6KtrSRHK+fVD31erE5FEMahAw5PmVCgD7MUXodq3pdZSUkqA9Cda2iWx6s1XYwiJWRmw==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.1.1" }, @@ -7896,9 +6917,8 @@ }, "node_modules/windows-release/node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -7919,9 +6939,8 @@ }, "node_modules/windows-release/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7931,27 +6950,24 @@ }, "node_modules/windows-release/node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/windows-release/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/windows-release/node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -7961,9 +6977,8 @@ }, "node_modules/windows-release/node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7976,24 +6991,21 @@ }, "node_modules/windows-release/node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/workerpool": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8005,15 +7017,13 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -8023,9 +7033,8 @@ }, "node_modules/xdg-basedir": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -8035,24 +7044,21 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -8068,18 +7074,16 @@ }, "node_modules/yargs-parser": { "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -8092,9 +7096,8 @@ }, "node_modules/yargs-unparser/node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8104,9 +7107,8 @@ }, "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8116,9 +7118,8 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8128,7 +7129,7 @@ }, "packages/bloom": { "name": "@redis/bloom", - "version": "2.0.0-next.3", + "version": "5.0.0-next.5", "license": "MIT", "devDependencies": { "@redis/test-utils": "*" @@ -8137,12 +7138,12 @@ "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^2.0.0-next.4" + "@redis/client": "^5.0.0-next.5" } }, "packages/client": { "name": "@redis/client", - "version": "2.0.0-next.4", + "version": "5.0.0-next.5", "license": "MIT", "dependencies": { "cluster-key-slot": "1.1.2" @@ -8158,7 +7159,7 @@ }, "packages/graph": { "name": "@redis/graph", - "version": "2.0.0-next.2", + "version": "5.0.0-next.5", "license": "MIT", "devDependencies": { "@redis/test-utils": "*" @@ -8167,12 +7168,12 @@ "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^2.0.0-next.4" + "@redis/client": "^5.0.0-next.5" } }, "packages/json": { "name": "@redis/json", - "version": "2.0.0-next.2", + "version": "5.0.0-next.5", "license": "MIT", "devDependencies": { "@redis/test-utils": "*" @@ -8181,19 +7182,19 @@ "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^2.0.0-next.4" + "@redis/client": "^5.0.0-next.5" } }, "packages/redis": { - "version": "5.0.0-next.4", + "version": "5.0.0-next.5", "license": "MIT", "dependencies": { - "@redis/bloom": "2.0.0-next.3", - "@redis/client": "2.0.0-next.4", - "@redis/graph": "2.0.0-next.2", - "@redis/json": "2.0.0-next.2", - "@redis/search": "2.0.0-next.2", - "@redis/time-series": "2.0.0-next.2" + "@redis/bloom": "5.0.0-next.5", + "@redis/client": "5.0.0-next.5", + "@redis/graph": "5.0.0-next.5", + "@redis/json": "5.0.0-next.5", + "@redis/search": "5.0.0-next.5", + "@redis/time-series": "5.0.0-next.5" }, "engines": { "node": ">= 18" @@ -8201,7 +7202,7 @@ }, "packages/search": { "name": "@redis/search", - "version": "2.0.0-next.2", + "version": "5.0.0-next.5", "license": "MIT", "devDependencies": { "@redis/test-utils": "*" @@ -8210,7 +7211,7 @@ "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^2.0.0-next.4" + "@redis/client": "^5.0.0-next.5" } }, "packages/test-utils": { @@ -8225,9 +7226,8 @@ }, "packages/test-utils/node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -8239,9 +7239,8 @@ }, "packages/test-utils/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8256,9 +7255,8 @@ }, "packages/test-utils/node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -8274,16 +7272,15 @@ }, "packages/test-utils/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "packages/time-series": { "name": "@redis/time-series", - "version": "2.0.0-next.2", + "version": "5.0.0-next.5", "license": "MIT", "devDependencies": { "@redis/test-utils": "*" @@ -8292,7 +7289,7 @@ "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^2.0.0-next.4" + "@redis/client": "^5.0.0-next.5" } } } diff --git a/packages/bloom/lib/commands/bloom/ADD.spec.ts b/packages/bloom/lib/commands/bloom/ADD.spec.ts index 11267e2afd..a229936c7d 100644 --- a/packages/bloom/lib/commands/bloom/ADD.spec.ts +++ b/packages/bloom/lib/commands/bloom/ADD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import ADD from './ADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.ADD', () => { it('transformArguments', () => { assert.deepEqual( - ADD.transformArguments('key', 'item'), + parseArgs(ADD, 'key', 'item'), ['BF.ADD', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/bloom/ADD.ts b/packages/bloom/lib/commands/bloom/ADD.ts index a965575489..f394755acc 100644 --- a/packages/bloom/lib/commands/bloom/ADD.ts +++ b/packages/bloom/lib/commands/bloom/ADD.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['BF.ADD', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('BF.ADD'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/CARD.spec.ts b/packages/bloom/lib/commands/bloom/CARD.spec.ts index b150f81257..32a28cdf6f 100644 --- a/packages/bloom/lib/commands/bloom/CARD.spec.ts +++ b/packages/bloom/lib/commands/bloom/CARD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import CARD from './CARD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.CARD', () => { it('transformArguments', () => { assert.deepEqual( - CARD.transformArguments('bloom'), + parseArgs(CARD, 'bloom'), ['BF.CARD', 'bloom'] ); }); diff --git a/packages/bloom/lib/commands/bloom/CARD.ts b/packages/bloom/lib/commands/bloom/CARD.ts index ddaa76cc1f..1d206b30af 100644 --- a/packages/bloom/lib/commands/bloom/CARD.ts +++ b/packages/bloom/lib/commands/bloom/CARD.ts @@ -1,10 +1,11 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['BF.CARD', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('BF.CARD'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/EXISTS.spec.ts b/packages/bloom/lib/commands/bloom/EXISTS.spec.ts index 7db891b92b..4d2cc70074 100644 --- a/packages/bloom/lib/commands/bloom/EXISTS.spec.ts +++ b/packages/bloom/lib/commands/bloom/EXISTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import EXISTS from './EXISTS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.EXISTS', () => { it('transformArguments', () => { assert.deepEqual( - EXISTS.transformArguments('key', 'item'), + parseArgs(EXISTS, 'key', 'item'), ['BF.EXISTS', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/bloom/EXISTS.ts b/packages/bloom/lib/commands/bloom/EXISTS.ts index 9d28d671d6..3de18dd07c 100644 --- a/packages/bloom/lib/commands/bloom/EXISTS.ts +++ b/packages/bloom/lib/commands/bloom/EXISTS.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['BF.EXISTS', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('BF.EXISTS'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/INFO.spec.ts b/packages/bloom/lib/commands/bloom/INFO.spec.ts index 4a17dab8d3..0dbe5cb1f4 100644 --- a/packages/bloom/lib/commands/bloom/INFO.spec.ts +++ b/packages/bloom/lib/commands/bloom/INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INFO from './INFO'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('bloom'), + parseArgs(INFO, 'bloom'), ['BF.INFO', 'bloom'] ); }); diff --git a/packages/bloom/lib/commands/bloom/INFO.ts b/packages/bloom/lib/commands/bloom/INFO.ts index 208c999b97..b1e3f137c8 100644 --- a/packages/bloom/lib/commands/bloom/INFO.ts +++ b/packages/bloom/lib/commands/bloom/INFO.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, UnwrapReply, NullReply, NumberReply, TuplesToMapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, UnwrapReply, NullReply, NumberReply, TuplesToMapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/lib/RESP/types'; import { transformInfoV2Reply } from '.'; export type BfInfoReplyMap = TuplesToMapReply<[ @@ -9,19 +10,11 @@ export type BfInfoReplyMap = TuplesToMapReply<[ [SimpleStringReply<'Expansion rate'>, NullReply | NumberReply] ]>; -export interface BfInfoReply { - capacity: NumberReply; - size: NumberReply; - numberOfFilters: NumberReply; - numberOfInsertedItems: NumberReply; - expansionRate: NullReply | NumberReply; -} - export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['BF.INFO', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('BF.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, _, typeMapping?: TypeMapping): BfInfoReplyMap => { diff --git a/packages/bloom/lib/commands/bloom/INSERT.spec.ts b/packages/bloom/lib/commands/bloom/INSERT.spec.ts index ccd81e070f..a9b544a51a 100644 --- a/packages/bloom/lib/commands/bloom/INSERT.spec.ts +++ b/packages/bloom/lib/commands/bloom/INSERT.spec.ts @@ -1,54 +1,55 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INSERT from './INSERT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.INSERT', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item'), + parseArgs(INSERT, 'key', 'item'), ['BF.INSERT', 'key', 'ITEMS', 'item'] ); }); it('with CAPACITY', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { CAPACITY: 100 }), + parseArgs(INSERT, 'key', 'item', { CAPACITY: 100 }), ['BF.INSERT', 'key', 'CAPACITY', '100', 'ITEMS', 'item'] ); }); it('with ERROR', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { ERROR: 0.01 }), + parseArgs(INSERT, 'key', 'item', { ERROR: 0.01 }), ['BF.INSERT', 'key', 'ERROR', '0.01', 'ITEMS', 'item'] ); }); it('with EXPANSION', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { EXPANSION: 1 }), + parseArgs(INSERT, 'key', 'item', { EXPANSION: 1 }), ['BF.INSERT', 'key', 'EXPANSION', '1', 'ITEMS', 'item'] ); }); it('with NOCREATE', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { NOCREATE: true }), + parseArgs(INSERT, 'key', 'item', { NOCREATE: true }), ['BF.INSERT', 'key', 'NOCREATE', 'ITEMS', 'item'] ); }); it('with NONSCALING', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { NONSCALING: true }), + parseArgs(INSERT, 'key', 'item', { NONSCALING: true }), ['BF.INSERT', 'key', 'NONSCALING', 'ITEMS', 'item'] ); }); it('with CAPACITY, ERROR, EXPANSION, NOCREATE and NONSCALING', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { + parseArgs(INSERT, 'key', 'item', { CAPACITY: 100, ERROR: 0.01, EXPANSION: 1, diff --git a/packages/bloom/lib/commands/bloom/INSERT.ts b/packages/bloom/lib/commands/bloom/INSERT.ts index dfeaf5f20d..14831f2f11 100644 --- a/packages/bloom/lib/commands/bloom/INSERT.ts +++ b/packages/bloom/lib/commands/bloom/INSERT.ts @@ -1,6 +1,7 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; -import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { transformBooleanArrayReply } from '@redis/client/lib/commands/generic-transformers'; export interface BfInsertOptions { CAPACITY?: number; @@ -11,37 +12,38 @@ export interface BfInsertOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument, options?: BfInsertOptions ) { - const args = ['BF.INSERT', key]; + parser.push('BF.INSERT'); + parser.pushKey(key); if (options?.CAPACITY !== undefined) { - args.push('CAPACITY', options.CAPACITY.toString()); + parser.push('CAPACITY', options.CAPACITY.toString()); } if (options?.ERROR !== undefined) { - args.push('ERROR', options.ERROR.toString()); + parser.push('ERROR', options.ERROR.toString()); } if (options?.EXPANSION !== undefined) { - args.push('EXPANSION', options.EXPANSION.toString()); + parser.push('EXPANSION', options.EXPANSION.toString()); } if (options?.NOCREATE) { - args.push('NOCREATE'); + parser.push('NOCREATE'); } if (options?.NONSCALING) { - args.push('NONSCALING'); + parser.push('NONSCALING'); } - args.push('ITEMS'); - return pushVariadicArguments(args, items); + parser.push('ITEMS'); + parser.pushVariadic(items); }, transformReply: transformBooleanArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/LOADCHUNK.spec.ts b/packages/bloom/lib/commands/bloom/LOADCHUNK.spec.ts index f958863c0d..40e24f96c3 100644 --- a/packages/bloom/lib/commands/bloom/LOADCHUNK.spec.ts +++ b/packages/bloom/lib/commands/bloom/LOADCHUNK.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import LOADCHUNK from './LOADCHUNK'; import { RESP_TYPES } from '@redis/client'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.LOADCHUNK', () => { it('transformArguments', () => { assert.deepEqual( - LOADCHUNK.transformArguments('key', 0, ''), + parseArgs(LOADCHUNK, 'key', 0, ''), ['BF.LOADCHUNK', 'key', '0', ''] ); }); diff --git a/packages/bloom/lib/commands/bloom/LOADCHUNK.ts b/packages/bloom/lib/commands/bloom/LOADCHUNK.ts index feade2fac4..47036e042a 100644 --- a/packages/bloom/lib/commands/bloom/LOADCHUNK.ts +++ b/packages/bloom/lib/commands/bloom/LOADCHUNK.ts @@ -1,10 +1,12 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, iterator: number, chunk: RedisArgument) { - return ['BF.LOADCHUNK', key, iterator.toString(), chunk]; + parseCommand(parser: CommandParser, key: RedisArgument, iterator: number, chunk: RedisArgument) { + parser.push('BF.LOADCHUNK'); + parser.pushKey(key); + parser.push(iterator.toString(), chunk); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/MADD.spec.ts b/packages/bloom/lib/commands/bloom/MADD.spec.ts index 5241a09485..5eb39ee73d 100644 --- a/packages/bloom/lib/commands/bloom/MADD.spec.ts +++ b/packages/bloom/lib/commands/bloom/MADD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MADD from './MADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.MADD', () => { it('transformArguments', () => { assert.deepEqual( - MADD.transformArguments('key', ['1', '2']), + parseArgs(MADD, 'key', ['1', '2']), ['BF.MADD', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/bloom/MADD.ts b/packages/bloom/lib/commands/bloom/MADD.ts index afb122476f..fda7419bf1 100644 --- a/packages/bloom/lib/commands/bloom/MADD.ts +++ b/packages/bloom/lib/commands/bloom/MADD.ts @@ -1,12 +1,14 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; -import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { transformBooleanArrayReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['BF.MADD', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('BF.MADD'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: transformBooleanArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/MEXISTS.spec.ts b/packages/bloom/lib/commands/bloom/MEXISTS.spec.ts index 0f313ba636..60c09b00f1 100644 --- a/packages/bloom/lib/commands/bloom/MEXISTS.spec.ts +++ b/packages/bloom/lib/commands/bloom/MEXISTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MEXISTS from './MEXISTS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.MEXISTS', () => { it('transformArguments', () => { assert.deepEqual( - MEXISTS.transformArguments('key', ['1', '2']), + parseArgs(MEXISTS, 'key', ['1', '2']), ['BF.MEXISTS', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/bloom/MEXISTS.ts b/packages/bloom/lib/commands/bloom/MEXISTS.ts index a23b713b50..acd85786f9 100644 --- a/packages/bloom/lib/commands/bloom/MEXISTS.ts +++ b/packages/bloom/lib/commands/bloom/MEXISTS.ts @@ -1,12 +1,14 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; -import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { transformBooleanArrayReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['BF.MEXISTS', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('BF.MEXISTS'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: transformBooleanArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/RESERVE.spec.ts b/packages/bloom/lib/commands/bloom/RESERVE.spec.ts index caf40d4a48..803577b350 100644 --- a/packages/bloom/lib/commands/bloom/RESERVE.spec.ts +++ b/packages/bloom/lib/commands/bloom/RESERVE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import RESERVE from './RESERVE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.RESERVE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - RESERVE.transformArguments('key', 0.01, 100), + parseArgs(RESERVE, 'key', 0.01, 100), ['BF.RESERVE', 'key', '0.01', '100'] ); }); it('with EXPANSION', () => { assert.deepEqual( - RESERVE.transformArguments('key', 0.01, 100, { + parseArgs(RESERVE, 'key', 0.01, 100, { EXPANSION: 1 }), ['BF.RESERVE', 'key', '0.01', '100', 'EXPANSION', '1'] @@ -22,7 +23,7 @@ describe('BF.RESERVE', () => { it('with NONSCALING', () => { assert.deepEqual( - RESERVE.transformArguments('key', 0.01, 100, { + parseArgs(RESERVE, 'key', 0.01, 100, { NONSCALING: true }), ['BF.RESERVE', 'key', '0.01', '100', 'NONSCALING'] @@ -31,7 +32,7 @@ describe('BF.RESERVE', () => { it('with EXPANSION and NONSCALING', () => { assert.deepEqual( - RESERVE.transformArguments('key', 0.01, 100, { + parseArgs(RESERVE, 'key', 0.01, 100, { EXPANSION: 1, NONSCALING: true }), diff --git a/packages/bloom/lib/commands/bloom/RESERVE.ts b/packages/bloom/lib/commands/bloom/RESERVE.ts index 6bccb1d1d1..aff155ab76 100644 --- a/packages/bloom/lib/commands/bloom/RESERVE.ts +++ b/packages/bloom/lib/commands/bloom/RESERVE.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export interface BfReserveOptions { EXPANSION?: number; @@ -6,25 +7,25 @@ export interface BfReserveOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, errorRate: number, capacity: number, options?: BfReserveOptions ) { - const args = ['BF.RESERVE', key, errorRate.toString(), capacity.toString()]; + parser.push('BF.RESERVE'); + parser.pushKey(key); + parser.push(errorRate.toString(), capacity.toString()); if (options?.EXPANSION) { - args.push('EXPANSION', options.EXPANSION.toString()); + parser.push('EXPANSION', options.EXPANSION.toString()); } if (options?.NONSCALING) { - args.push('NONSCALING'); + parser.push('NONSCALING'); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/bloom/SCANDUMP.spec.ts b/packages/bloom/lib/commands/bloom/SCANDUMP.spec.ts index a7de98eabe..a41a6e8e46 100644 --- a/packages/bloom/lib/commands/bloom/SCANDUMP.spec.ts +++ b/packages/bloom/lib/commands/bloom/SCANDUMP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import SCANDUMP from './SCANDUMP'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('BF.SCANDUMP', () => { it('transformArguments', () => { assert.deepEqual( - SCANDUMP.transformArguments('key', 0), + parseArgs(SCANDUMP, 'key', 0), ['BF.SCANDUMP', 'key', '0'] ); }); diff --git a/packages/bloom/lib/commands/bloom/SCANDUMP.ts b/packages/bloom/lib/commands/bloom/SCANDUMP.ts index 588957b174..37b1f57045 100644 --- a/packages/bloom/lib/commands/bloom/SCANDUMP.ts +++ b/packages/bloom/lib/commands/bloom/SCANDUMP.ts @@ -1,10 +1,12 @@ -import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, iterator: number) { - return ['BF.SCANDUMP', key, iterator.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, iterator: number) { + parser.push('BF.SCANDUMP'); + parser.pushKey(key); + parser.push(iterator.toString()); }, transformReply(reply: UnwrapReply>) { return { diff --git a/packages/bloom/lib/commands/bloom/index.ts b/packages/bloom/lib/commands/bloom/index.ts index a93f79c9c5..e87f57220d 100644 --- a/packages/bloom/lib/commands/bloom/index.ts +++ b/packages/bloom/lib/commands/bloom/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands, TypeMapping } from '@redis/client/lib/RESP/types'; import ADD from './ADD'; import CARD from './CARD'; diff --git a/packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts b/packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts index 1d2921cab7..44ccaf6046 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INCRBY from './INCRBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.INCRBY', () => { describe('transformArguments', () => { it('single item', () => { assert.deepEqual( - INCRBY.transformArguments('key', { + parseArgs(INCRBY, 'key', { item: 'item', incrementBy: 1 }), @@ -16,7 +17,7 @@ describe('CMS.INCRBY', () => { it('multiple items', () => { assert.deepEqual( - INCRBY.transformArguments('key', [{ + parseArgs(INCRBY, 'key', [{ item: 'a', incrementBy: 1 }, { diff --git a/packages/bloom/lib/commands/count-min-sketch/INCRBY.ts b/packages/bloom/lib/commands/count-min-sketch/INCRBY.ts index 1dfbabbaa4..39cc52d31d 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INCRBY.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INCRBY.ts @@ -1,4 +1,5 @@ -import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface BfIncrByItem { item: RedisArgument; @@ -6,27 +7,26 @@ export interface BfIncrByItem { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, items: BfIncrByItem | Array ) { - const args = ['CMS.INCRBY', key]; + parser.push('CMS.INCRBY'); + parser.pushKey(key); if (Array.isArray(items)) { for (const item of items) { - pushIncrByItem(args, item); + pushIncrByItem(parser, item); } } else { - pushIncrByItem(args, items); + pushIncrByItem(parser, items); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; -function pushIncrByItem(args: Array, { item, incrementBy }: BfIncrByItem): void { - args.push(item, incrementBy.toString()); +function pushIncrByItem(parser: CommandParser, { item, incrementBy }: BfIncrByItem): void { + parser.push(item, incrementBy.toString()); } diff --git a/packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts b/packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts index e650d78d2e..cbc8065016 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INFO from './INFO'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('key'), + parseArgs(INFO, 'key'), ['CMS.INFO', 'key'] ); }); diff --git a/packages/bloom/lib/commands/count-min-sketch/INFO.ts b/packages/bloom/lib/commands/count-min-sketch/INFO.ts index e4aae5bf47..9b77409f2d 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INFO.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INFO.ts @@ -1,4 +1,5 @@ -import { RedisArgument, TuplesToMapReply, NumberReply, UnwrapReply, Resp2Reply, Command, SimpleStringReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, TuplesToMapReply, NumberReply, UnwrapReply, Resp2Reply, Command, SimpleStringReply, TypeMapping } from '@redis/client/lib/RESP/types'; import { transformInfoV2Reply } from '../bloom'; export type CmsInfoReplyMap = TuplesToMapReply<[ @@ -14,10 +15,10 @@ export interface CmsInfoReply { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['CMS.INFO', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('CMS.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, _, typeMapping?: TypeMapping): CmsInfoReply => { diff --git a/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.spec.ts b/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.spec.ts index a3d27c17df..9fa1652a2e 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INITBYDIM from './INITBYDIM'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.INITBYDIM', () => { it('transformArguments', () => { assert.deepEqual( - INITBYDIM.transformArguments('key', 1000, 5), + parseArgs(INITBYDIM, 'key', 1000, 5), ['CMS.INITBYDIM', 'key', '1000', '5'] ); }); diff --git a/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.ts b/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.ts index 60790d421e..cd295d0696 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INITBYDIM.ts @@ -1,10 +1,12 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, width: number, depth: number) { - return ['CMS.INITBYDIM', key, width.toString(), depth.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, width: number, depth: number) { + parser.push('CMS.INITBYDIM'); + parser.pushKey(key); + parser.push(width.toString(), depth.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.spec.ts b/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.spec.ts index 8df62020e8..b59bc14494 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INITBYPROB from './INITBYPROB'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.INITBYPROB', () => { it('transformArguments', () => { assert.deepEqual( - INITBYPROB.transformArguments('key', 0.001, 0.01), + parseArgs(INITBYPROB, 'key', 0.001, 0.01), ['CMS.INITBYPROB', 'key', '0.001', '0.01'] ); }); diff --git a/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.ts b/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.ts index 7b21755f17..e7e85d4100 100644 --- a/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.ts +++ b/packages/bloom/lib/commands/count-min-sketch/INITBYPROB.ts @@ -1,10 +1,12 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, error: number, probability: number) { - return ['CMS.INITBYPROB', key, error.toString(), probability.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, error: number, probability: number) { + parser.push('CMS.INITBYPROB'); + parser.pushKey(key); + parser.push(error.toString(), probability.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts b/packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts index eef4bd403a..03e3d5c636 100644 --- a/packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MERGE from './MERGE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.MERGE', () => { describe('transformArguments', () => { it('without WEIGHTS', () => { assert.deepEqual( - MERGE.transformArguments('destination', ['source']), + parseArgs(MERGE, 'destination', ['source']), ['CMS.MERGE', 'destination', '1', 'source'] ); }); it('with WEIGHTS', () => { assert.deepEqual( - MERGE.transformArguments('destination', [{ + parseArgs(MERGE, 'destination', [{ name: 'source', weight: 1 }]), diff --git a/packages/bloom/lib/commands/count-min-sketch/MERGE.ts b/packages/bloom/lib/commands/count-min-sketch/MERGE.ts index 2e63065d1c..cc0fc92907 100644 --- a/packages/bloom/lib/commands/count-min-sketch/MERGE.ts +++ b/packages/bloom/lib/commands/count-min-sketch/MERGE.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; interface BfMergeSketch { name: RedisArgument; @@ -8,26 +9,27 @@ interface BfMergeSketch { export type BfMergeSketches = Array | Array; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, source: BfMergeSketches ) { - let args = ['CMS.MERGE', destination, source.length.toString()]; + parser.push('CMS.MERGE'); + parser.pushKey(destination); + parser.push(source.length.toString()); if (isPlainSketches(source)) { - args = args.concat(source); + parser.pushVariadic(source); } else { - const { length } = args; - args[length + source.length] = 'WEIGHTS'; for (let i = 0; i < source.length; i++) { - args[length + i] = source[i].name; - args[length + source.length + i + 1] = source[i].weight.toString(); + parser.push(source[i].name); + } + parser.push('WEIGHTS'); + for (let i = 0; i < source.length; i++) { + parser.push(source[i].weight.toString()) } } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts b/packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts index cc9c913b56..e12a519e96 100644 --- a/packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts +++ b/packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import QUERY from './QUERY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CMS.QUERY', () => { it('transformArguments', () => { assert.deepEqual( - QUERY.transformArguments('key', 'item'), + parseArgs(QUERY, 'key', 'item'), ['CMS.QUERY', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/count-min-sketch/QUERY.ts b/packages/bloom/lib/commands/count-min-sketch/QUERY.ts index 5d2905300b..54d838c193 100644 --- a/packages/bloom/lib/commands/count-min-sketch/QUERY.ts +++ b/packages/bloom/lib/commands/count-min-sketch/QUERY.ts @@ -1,11 +1,13 @@ -import { ArrayReply, NumberReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { ArrayReply, NumberReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['CMS.QUERY', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('CMS.QUERY'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/count-min-sketch/index.ts b/packages/bloom/lib/commands/count-min-sketch/index.ts index 4f0f395ca3..1132a7524e 100644 --- a/packages/bloom/lib/commands/count-min-sketch/index.ts +++ b/packages/bloom/lib/commands/count-min-sketch/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands } from '@redis/client/lib/RESP/types'; import INCRBY from './INCRBY'; import INFO from './INFO'; import INITBYDIM from './INITBYDIM'; diff --git a/packages/bloom/lib/commands/cuckoo/ADD.spec.ts b/packages/bloom/lib/commands/cuckoo/ADD.spec.ts index fa610cc666..7fa518fea8 100644 --- a/packages/bloom/lib/commands/cuckoo/ADD.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/ADD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import ADD from './ADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.ADD', () => { it('transformArguments', () => { assert.deepEqual( - ADD.transformArguments('key', 'item'), + parseArgs(ADD, 'key', 'item'), ['CF.ADD', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/ADD.ts b/packages/bloom/lib/commands/cuckoo/ADD.ts index 52e98a801d..3d0dc77be2 100644 --- a/packages/bloom/lib/commands/cuckoo/ADD.ts +++ b/packages/bloom/lib/commands/cuckoo/ADD.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['CF.ADD', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('CF.ADD'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/ADDNX.spec.ts b/packages/bloom/lib/commands/cuckoo/ADDNX.spec.ts index f50ad87dc1..c142733ce4 100644 --- a/packages/bloom/lib/commands/cuckoo/ADDNX.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/ADDNX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import ADDNX from './ADDNX'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.ADDNX', () => { it('transformArguments', () => { assert.deepEqual( - ADDNX.transformArguments('key', 'item'), + parseArgs(ADDNX, 'key', 'item'), ['CF.ADDNX', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/ADDNX.ts b/packages/bloom/lib/commands/cuckoo/ADDNX.ts index c739077ee4..f358f1581e 100644 --- a/packages/bloom/lib/commands/cuckoo/ADDNX.ts +++ b/packages/bloom/lib/commands/cuckoo/ADDNX.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['CF.ADDNX', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('CF.ADDNX'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/COUNT.spec.ts b/packages/bloom/lib/commands/cuckoo/COUNT.spec.ts index ff8d40f064..9393494d85 100644 --- a/packages/bloom/lib/commands/cuckoo/COUNT.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import COUNT from './COUNT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.COUNT', () => { it('transformArguments', () => { assert.deepEqual( - COUNT.transformArguments('key', 'item'), + parseArgs(COUNT, 'key', 'item'), ['CF.COUNT', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/COUNT.ts b/packages/bloom/lib/commands/cuckoo/COUNT.ts index 2284edff17..512b014327 100644 --- a/packages/bloom/lib/commands/cuckoo/COUNT.ts +++ b/packages/bloom/lib/commands/cuckoo/COUNT.ts @@ -1,10 +1,12 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['CF.COUNT', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('CF.COUNT'); + parser.pushKey(key); + parser.push(item); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/DEL.spec.ts b/packages/bloom/lib/commands/cuckoo/DEL.spec.ts index e02b5636e1..41ed653bfc 100644 --- a/packages/bloom/lib/commands/cuckoo/DEL.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/DEL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import DEL from './DEL'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.DEL', () => { it('transformArguments', () => { assert.deepEqual( - DEL.transformArguments('key', 'item'), + parseArgs(DEL, 'key', 'item'), ['CF.DEL', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/DEL.ts b/packages/bloom/lib/commands/cuckoo/DEL.ts index 0af8ebc851..0b2bdaea99 100644 --- a/packages/bloom/lib/commands/cuckoo/DEL.ts +++ b/packages/bloom/lib/commands/cuckoo/DEL.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['CF.DEL', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('CF.DEL'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/EXISTS.spec.ts b/packages/bloom/lib/commands/cuckoo/EXISTS.spec.ts index 899c11e839..f77a9d69ef 100644 --- a/packages/bloom/lib/commands/cuckoo/EXISTS.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/EXISTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import EXISTS from './EXISTS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.EXISTS', () => { it('transformArguments', () => { assert.deepEqual( - EXISTS.transformArguments('key', 'item'), + parseArgs(EXISTS, 'key', 'item'), ['CF.EXISTS', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/EXISTS.ts b/packages/bloom/lib/commands/cuckoo/EXISTS.ts index 8fd74ca47c..ef93462990 100644 --- a/packages/bloom/lib/commands/cuckoo/EXISTS.ts +++ b/packages/bloom/lib/commands/cuckoo/EXISTS.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformBooleanReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, item: RedisArgument) { - return ['CF.EXISTS', key, item]; + parseCommand(parser: CommandParser, key: RedisArgument, item: RedisArgument) { + parser.push('CF.EXISTS'); + parser.pushKey(key); + parser.push(item); }, transformReply: transformBooleanReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/INFO.spec.ts b/packages/bloom/lib/commands/cuckoo/INFO.spec.ts index 222177c465..c5503ed113 100644 --- a/packages/bloom/lib/commands/cuckoo/INFO.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INFO from './INFO'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('cuckoo'), + parseArgs(INFO, 'cuckoo'), ['CF.INFO', 'cuckoo'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/INFO.ts b/packages/bloom/lib/commands/cuckoo/INFO.ts index 70a7d80c6f..15972b206f 100644 --- a/packages/bloom/lib/commands/cuckoo/INFO.ts +++ b/packages/bloom/lib/commands/cuckoo/INFO.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, NumberReply, TuplesToMapReply, UnwrapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, NumberReply, TuplesToMapReply, UnwrapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/lib/RESP/types'; import { transformInfoV2Reply } from '../bloom'; export type CfInfoReplyMap = TuplesToMapReply<[ @@ -13,10 +14,10 @@ export type CfInfoReplyMap = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['CF.INFO', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('CF.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, _, typeMapping?: TypeMapping): CfInfoReplyMap => { diff --git a/packages/bloom/lib/commands/cuckoo/INSERT.spec.ts b/packages/bloom/lib/commands/cuckoo/INSERT.spec.ts index 096cf54709..dc2bd57451 100644 --- a/packages/bloom/lib/commands/cuckoo/INSERT.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/INSERT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INSERT from './INSERT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.INSERT', () => { it('transformArguments', () => { assert.deepEqual( - INSERT.transformArguments('key', 'item', { + parseArgs(INSERT, 'key', 'item', { CAPACITY: 100, NOCREATE: true }), diff --git a/packages/bloom/lib/commands/cuckoo/INSERT.ts b/packages/bloom/lib/commands/cuckoo/INSERT.ts index d6df64eea1..75534e0a7f 100644 --- a/packages/bloom/lib/commands/cuckoo/INSERT.ts +++ b/packages/bloom/lib/commands/cuckoo/INSERT.ts @@ -1,34 +1,37 @@ -import { Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments, transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument, transformBooleanArrayReply } from '@redis/client/lib/commands/generic-transformers'; export interface CfInsertOptions { CAPACITY?: number; NOCREATE?: boolean; } -export function transofrmCfInsertArguments( - command: RedisArgument, +export function parseCfInsertArguments( + parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument, options?: CfInsertOptions ) { - const args = [command, key]; + parser.pushKey(key); if (options?.CAPACITY !== undefined) { - args.push('CAPACITY', options.CAPACITY.toString()); + parser.push('CAPACITY', options.CAPACITY.toString()); } if (options?.NOCREATE) { - args.push('NOCREATE'); + parser.push('NOCREATE'); } - args.push('ITEMS'); - return pushVariadicArguments(args, items); + parser.push('ITEMS'); + parser.pushVariadic(items); } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments: transofrmCfInsertArguments.bind(undefined, 'CF.INSERT'), + parseCommand(...args: Parameters) { + args[0].push('CF.INSERT'); + parseCfInsertArguments(...args); + }, transformReply: transformBooleanArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/INSERTNX.spec.ts b/packages/bloom/lib/commands/cuckoo/INSERTNX.spec.ts index 0f87427822..648d9be7ac 100644 --- a/packages/bloom/lib/commands/cuckoo/INSERTNX.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/INSERTNX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INSERTNX from './INSERTNX'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.INSERTNX', () => { it('transformArguments', () => { assert.deepEqual( - INSERTNX.transformArguments('key', 'item', { + parseArgs(INSERTNX, 'key', 'item', { CAPACITY: 100, NOCREATE: true }), diff --git a/packages/bloom/lib/commands/cuckoo/INSERTNX.ts b/packages/bloom/lib/commands/cuckoo/INSERTNX.ts index 5cd56e794f..581cfcd9e6 100644 --- a/packages/bloom/lib/commands/cuckoo/INSERTNX.ts +++ b/packages/bloom/lib/commands/cuckoo/INSERTNX.ts @@ -1,9 +1,11 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; -import INSERT, { transofrmCfInsertArguments } from './INSERT'; +import { Command } from '@redis/client/lib/RESP/types'; +import INSERT, { parseCfInsertArguments } from './INSERT'; export default { - FIRST_KEY_INDEX: INSERT.FIRST_KEY_INDEX, IS_READ_ONLY: INSERT.IS_READ_ONLY, - transformArguments: transofrmCfInsertArguments.bind(undefined, 'CF.INSERTNX'), + parseCommand(...args: Parameters) { + args[0].push('CF.INSERTNX'); + parseCfInsertArguments(...args); + }, transformReply: INSERT.transformReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/LOADCHUNK.spec.ts b/packages/bloom/lib/commands/cuckoo/LOADCHUNK.spec.ts index 5b880e0dd9..5415c787dd 100644 --- a/packages/bloom/lib/commands/cuckoo/LOADCHUNK.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/LOADCHUNK.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import LOADCHUNK from './LOADCHUNK'; import { RESP_TYPES } from '@redis/client'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.LOADCHUNK', () => { it('transformArguments', () => { assert.deepEqual( - LOADCHUNK.transformArguments('item', 0, ''), + parseArgs(LOADCHUNK, 'item', 0, ''), ['CF.LOADCHUNK', 'item', '0', ''] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/LOADCHUNK.ts b/packages/bloom/lib/commands/cuckoo/LOADCHUNK.ts index 08cb749b59..420774a650 100644 --- a/packages/bloom/lib/commands/cuckoo/LOADCHUNK.ts +++ b/packages/bloom/lib/commands/cuckoo/LOADCHUNK.ts @@ -1,10 +1,12 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, iterator: number, chunk: RedisArgument) { - return ['CF.LOADCHUNK', key, iterator.toString(), chunk]; + parseCommand(parser: CommandParser, key: RedisArgument, iterator: number, chunk: RedisArgument) { + parser.push('CF.LOADCHUNK'); + parser.pushKey(key); + parser.push(iterator.toString(), chunk); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/RESERVE.spec.ts b/packages/bloom/lib/commands/cuckoo/RESERVE.spec.ts index b8f2556bc4..53546e4156 100644 --- a/packages/bloom/lib/commands/cuckoo/RESERVE.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/RESERVE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import RESERVE from './RESERVE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.RESERVE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - RESERVE.transformArguments('key', 4), + parseArgs(RESERVE, 'key', 4), ['CF.RESERVE', 'key', '4'] ); }); it('with EXPANSION', () => { assert.deepEqual( - RESERVE.transformArguments('key', 4, { + parseArgs(RESERVE, 'key', 4, { EXPANSION: 1 }), ['CF.RESERVE', 'key', '4', 'EXPANSION', '1'] @@ -22,7 +23,7 @@ describe('CF.RESERVE', () => { it('with BUCKETSIZE', () => { assert.deepEqual( - RESERVE.transformArguments('key', 4, { + parseArgs(RESERVE, 'key', 4, { BUCKETSIZE: 2 }), ['CF.RESERVE', 'key', '4', 'BUCKETSIZE', '2'] @@ -31,7 +32,7 @@ describe('CF.RESERVE', () => { it('with MAXITERATIONS', () => { assert.deepEqual( - RESERVE.transformArguments('key', 4, { + parseArgs(RESERVE, 'key', 4, { MAXITERATIONS: 1 }), ['CF.RESERVE', 'key', '4', 'MAXITERATIONS', '1'] diff --git a/packages/bloom/lib/commands/cuckoo/RESERVE.ts b/packages/bloom/lib/commands/cuckoo/RESERVE.ts index bc80daa008..ba401dcdee 100644 --- a/packages/bloom/lib/commands/cuckoo/RESERVE.ts +++ b/packages/bloom/lib/commands/cuckoo/RESERVE.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export interface CfReserveOptions { BUCKETSIZE?: number; @@ -7,28 +8,28 @@ export interface CfReserveOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, capacity: number, options?: CfReserveOptions ) { - const args = ['CF.RESERVE', key, capacity.toString()]; + parser.push('CF.RESERVE'); + parser.pushKey(key); + parser.push(capacity.toString()); if (options?.BUCKETSIZE !== undefined) { - args.push('BUCKETSIZE', options.BUCKETSIZE.toString()); + parser.push('BUCKETSIZE', options.BUCKETSIZE.toString()); } if (options?.MAXITERATIONS !== undefined) { - args.push('MAXITERATIONS', options.MAXITERATIONS.toString()); + parser.push('MAXITERATIONS', options.MAXITERATIONS.toString()); } if (options?.EXPANSION !== undefined) { - args.push('EXPANSION', options.EXPANSION.toString()); + parser.push('EXPANSION', options.EXPANSION.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/cuckoo/SCANDUMP.spec.ts b/packages/bloom/lib/commands/cuckoo/SCANDUMP.spec.ts index e1bac59d32..60a57ac46a 100644 --- a/packages/bloom/lib/commands/cuckoo/SCANDUMP.spec.ts +++ b/packages/bloom/lib/commands/cuckoo/SCANDUMP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import SCANDUMP from './SCANDUMP'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('CF.SCANDUMP', () => { it('transformArguments', () => { assert.deepEqual( - SCANDUMP.transformArguments('key', 0), + parseArgs(SCANDUMP, 'key', 0), ['CF.SCANDUMP', 'key', '0'] ); }); diff --git a/packages/bloom/lib/commands/cuckoo/SCANDUMP.ts b/packages/bloom/lib/commands/cuckoo/SCANDUMP.ts index dc07668928..aab7a5eecc 100644 --- a/packages/bloom/lib/commands/cuckoo/SCANDUMP.ts +++ b/packages/bloom/lib/commands/cuckoo/SCANDUMP.ts @@ -1,10 +1,12 @@ -import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, NullReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, NullReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, iterator: number) { - return ['CF.SCANDUMP', key, iterator.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, iterator: number) { + parser.push('CF.SCANDUMP'); + parser.pushKey(key); + parser.push(iterator.toString()); }, transformReply(reply: UnwrapReply>) { return { diff --git a/packages/bloom/lib/commands/cuckoo/index.ts b/packages/bloom/lib/commands/cuckoo/index.ts index 62c63fe8d1..7ee99b41cd 100644 --- a/packages/bloom/lib/commands/cuckoo/index.ts +++ b/packages/bloom/lib/commands/cuckoo/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands } from '@redis/client/lib/RESP/types'; import ADD from './ADD'; import ADDNX from './ADDNX'; import COUNT from './COUNT'; diff --git a/packages/bloom/lib/commands/t-digest/ADD.spec.ts b/packages/bloom/lib/commands/t-digest/ADD.spec.ts index 31d4957c6a..7578fb9378 100644 --- a/packages/bloom/lib/commands/t-digest/ADD.spec.ts +++ b/packages/bloom/lib/commands/t-digest/ADD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import ADD from './ADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.ADD', () => { it('transformArguments', () => { assert.deepEqual( - ADD.transformArguments('key', [1, 2]), + parseArgs(ADD, 'key', [1, 2]), ['TDIGEST.ADD', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/ADD.ts b/packages/bloom/lib/commands/t-digest/ADD.ts index e7c6d7c442..d9d67144a9 100644 --- a/packages/bloom/lib/commands/t-digest/ADD.ts +++ b/packages/bloom/lib/commands/t-digest/ADD.ts @@ -1,16 +1,15 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, values: Array) { - const args = ['TDIGEST.ADD', key]; + parseCommand(parser: CommandParser, key: RedisArgument, values: Array) { + parser.push('TDIGEST.ADD'); + parser.pushKey(key); for (const value of values) { - args.push(value.toString()); + parser.push(value.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/BYRANK.spec.ts b/packages/bloom/lib/commands/t-digest/BYRANK.spec.ts index a6443d7743..81a2c75dff 100644 --- a/packages/bloom/lib/commands/t-digest/BYRANK.spec.ts +++ b/packages/bloom/lib/commands/t-digest/BYRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import BYRANK from './BYRANK'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.BYRANK', () => { it('transformArguments', () => { assert.deepEqual( - BYRANK.transformArguments('key', [1, 2]), + parseArgs(BYRANK, 'key', [1, 2]), ['TDIGEST.BYRANK', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/BYRANK.ts b/packages/bloom/lib/commands/t-digest/BYRANK.ts index 8b48acd1b1..126c9963e7 100644 --- a/packages/bloom/lib/commands/t-digest/BYRANK.ts +++ b/packages/bloom/lib/commands/t-digest/BYRANK.ts @@ -1,24 +1,25 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleArrayReply } from '@redis/client/lib/commands/generic-transformers'; export function transformByRankArguments( - command: RedisArgument, + parser: CommandParser, key: RedisArgument, ranks: Array ) { - const args = [command, key]; + parser.pushKey(key); for (const rank of ranks) { - args.push(rank.toString()); + parser.push(rank.toString()); } - - return args; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: transformByRankArguments.bind(undefined, 'TDIGEST.BYRANK'), + parseCommand(...args: Parameters) { + args[0].push('TDIGEST.BYRANK'); + transformByRankArguments(...args); + }, transformReply: transformDoubleArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/BYREVRANK.spec.ts b/packages/bloom/lib/commands/t-digest/BYREVRANK.spec.ts index f5bb4e6281..c8f794bef5 100644 --- a/packages/bloom/lib/commands/t-digest/BYREVRANK.spec.ts +++ b/packages/bloom/lib/commands/t-digest/BYREVRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import BYREVRANK from './BYREVRANK'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.BYREVRANK', () => { it('transformArguments', () => { assert.deepEqual( - BYREVRANK.transformArguments('key', [1, 2]), + parseArgs(BYREVRANK, 'key', [1, 2]), ['TDIGEST.BYREVRANK', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/BYREVRANK.ts b/packages/bloom/lib/commands/t-digest/BYREVRANK.ts index 9f62b42d81..4995bf86cc 100644 --- a/packages/bloom/lib/commands/t-digest/BYREVRANK.ts +++ b/packages/bloom/lib/commands/t-digest/BYREVRANK.ts @@ -1,9 +1,11 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import BYRANK, { transformByRankArguments } from './BYRANK'; export default { - FIRST_KEY_INDEX: BYRANK.FIRST_KEY_INDEX, IS_READ_ONLY: BYRANK.IS_READ_ONLY, - transformArguments: transformByRankArguments.bind(undefined, 'TDIGEST.BYREVRANK'), + parseCommand(...args: Parameters) { + args[0].push('TDIGEST.BYREVRANK'); + transformByRankArguments(...args); + }, transformReply: BYRANK.transformReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/CDF.spec.ts b/packages/bloom/lib/commands/t-digest/CDF.spec.ts index 09208deba1..2689bf2fc9 100644 --- a/packages/bloom/lib/commands/t-digest/CDF.spec.ts +++ b/packages/bloom/lib/commands/t-digest/CDF.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import CDF from './CDF'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.CDF', () => { it('transformArguments', () => { assert.deepEqual( - CDF.transformArguments('key', [1, 2]), + parseArgs(CDF, 'key', [1, 2]), ['TDIGEST.CDF', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/CDF.ts b/packages/bloom/lib/commands/t-digest/CDF.ts index 0fbdedb3a4..e786dc4c8a 100644 --- a/packages/bloom/lib/commands/t-digest/CDF.ts +++ b/packages/bloom/lib/commands/t-digest/CDF.ts @@ -1,17 +1,16 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleArrayReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, values: Array) { - const args = ['TDIGEST.CDF', key]; + parseCommand(parser: CommandParser, key: RedisArgument, values: Array) { + parser.push('TDIGEST.CDF'); + parser.pushKey(key); for (const item of values) { - args.push(item.toString()); + parser.push(item.toString()); } - - return args; }, transformReply: transformDoubleArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/CREATE.spec.ts b/packages/bloom/lib/commands/t-digest/CREATE.spec.ts index 781b2a7e43..0f218e07ab 100644 --- a/packages/bloom/lib/commands/t-digest/CREATE.spec.ts +++ b/packages/bloom/lib/commands/t-digest/CREATE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import CREATE from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.CREATE', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - CREATE.transformArguments('key'), + parseArgs(CREATE, 'key'), ['TDIGEST.CREATE', 'key'] ); }); it('with COMPRESSION', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { COMPRESSION: 100 }), ['TDIGEST.CREATE', 'key', 'COMPRESSION', '100'] diff --git a/packages/bloom/lib/commands/t-digest/CREATE.ts b/packages/bloom/lib/commands/t-digest/CREATE.ts index 8b832487da..fd160cce84 100644 --- a/packages/bloom/lib/commands/t-digest/CREATE.ts +++ b/packages/bloom/lib/commands/t-digest/CREATE.ts @@ -1,20 +1,19 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export interface TDigestCreateOptions { COMPRESSION?: number; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: TDigestCreateOptions) { - const args = ['TDIGEST.CREATE', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: TDigestCreateOptions) { + parser.push('TDIGEST.CREATE'); + parser.pushKey(key); if (options?.COMPRESSION !== undefined) { - args.push('COMPRESSION', options.COMPRESSION.toString()); + parser.push('COMPRESSION', options.COMPRESSION.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/INFO.spec.ts b/packages/bloom/lib/commands/t-digest/INFO.spec.ts index 247f4ab0b6..d5b8b3e13e 100644 --- a/packages/bloom/lib/commands/t-digest/INFO.spec.ts +++ b/packages/bloom/lib/commands/t-digest/INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INFO from './INFO'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('key'), + parseArgs(INFO, 'key'), ['TDIGEST.INFO', 'key'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/INFO.ts b/packages/bloom/lib/commands/t-digest/INFO.ts index c7c2357d2b..43624e8f9b 100644 --- a/packages/bloom/lib/commands/t-digest/INFO.ts +++ b/packages/bloom/lib/commands/t-digest/INFO.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, NumberReply, TuplesToMapReply, UnwrapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, NumberReply, TuplesToMapReply, UnwrapReply, Resp2Reply, SimpleStringReply, TypeMapping } from '@redis/client/lib/RESP/types'; import { transformInfoV2Reply } from '../bloom'; export type TdInfoReplyMap = TuplesToMapReply<[ @@ -14,10 +15,10 @@ export type TdInfoReplyMap = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TDIGEST.INFO', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TDIGEST.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, _, typeMapping?: TypeMapping): TdInfoReplyMap => { diff --git a/packages/bloom/lib/commands/t-digest/MAX.spec.ts b/packages/bloom/lib/commands/t-digest/MAX.spec.ts index caa92b0a6a..920c9d1139 100644 --- a/packages/bloom/lib/commands/t-digest/MAX.spec.ts +++ b/packages/bloom/lib/commands/t-digest/MAX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MAX from './MAX'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.MAX', () => { it('transformArguments', () => { assert.deepEqual( - MAX.transformArguments('key'), + parseArgs(MAX, 'key'), ['TDIGEST.MAX', 'key'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/MAX.ts b/packages/bloom/lib/commands/t-digest/MAX.ts index ef778f832a..64852d8e6d 100644 --- a/packages/bloom/lib/commands/t-digest/MAX.ts +++ b/packages/bloom/lib/commands/t-digest/MAX.ts @@ -1,11 +1,12 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TDIGEST.MAX', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TDIGEST.MAX'); + parser.pushKey(key); }, transformReply: transformDoubleReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/MERGE.spec.ts b/packages/bloom/lib/commands/t-digest/MERGE.spec.ts index 1ee792e3a4..f2a7c1a119 100644 --- a/packages/bloom/lib/commands/t-digest/MERGE.spec.ts +++ b/packages/bloom/lib/commands/t-digest/MERGE.spec.ts @@ -1,20 +1,21 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MERGE from './MERGE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.MERGE', () => { describe('transformArguments', () => { describe('source', () => { it('string', () => { assert.deepEqual( - MERGE.transformArguments('destination', 'source'), + parseArgs(MERGE, 'destination', 'source'), ['TDIGEST.MERGE', 'destination', '1', 'source'] ); }); it('Array', () => { assert.deepEqual( - MERGE.transformArguments('destination', ['1', '2']), + parseArgs(MERGE, 'destination', ['1', '2']), ['TDIGEST.MERGE', 'destination', '2', '1', '2'] ); }); @@ -22,7 +23,7 @@ describe('TDIGEST.MERGE', () => { it('with COMPRESSION', () => { assert.deepEqual( - MERGE.transformArguments('destination', 'source', { + parseArgs(MERGE, 'destination', 'source', { COMPRESSION: 100 }), ['TDIGEST.MERGE', 'destination', '1', 'source', 'COMPRESSION', '100'] @@ -31,7 +32,7 @@ describe('TDIGEST.MERGE', () => { it('with OVERRIDE', () => { assert.deepEqual( - MERGE.transformArguments('destination', 'source', { + parseArgs(MERGE, 'destination', 'source', { OVERRIDE: true }), ['TDIGEST.MERGE', 'destination', '1', 'source', 'OVERRIDE'] diff --git a/packages/bloom/lib/commands/t-digest/MERGE.ts b/packages/bloom/lib/commands/t-digest/MERGE.ts index e9cd99aabf..1031f0e917 100644 --- a/packages/bloom/lib/commands/t-digest/MERGE.ts +++ b/packages/bloom/lib/commands/t-digest/MERGE.ts @@ -1,5 +1,6 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export interface TDigestMergeOptions { COMPRESSION?: number; @@ -7,24 +8,24 @@ export interface TDigestMergeOptions { } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, source: RedisVariadicArgument, options?: TDigestMergeOptions ) { - const args = pushVariadicArgument(['TDIGEST.MERGE', destination], source); + parser.push('TDIGEST.MERGE'); + parser.pushKey(destination); + parser.pushKeysLength(source); if (options?.COMPRESSION !== undefined) { - args.push('COMPRESSION', options.COMPRESSION.toString()); + parser.push('COMPRESSION', options.COMPRESSION.toString()); } if (options?.OVERRIDE) { - args.push('OVERRIDE'); + parser.push('OVERRIDE'); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/MIN.spec.ts b/packages/bloom/lib/commands/t-digest/MIN.spec.ts index 0d1637cc9b..278248ea46 100644 --- a/packages/bloom/lib/commands/t-digest/MIN.spec.ts +++ b/packages/bloom/lib/commands/t-digest/MIN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import MIN from './MIN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.MIN', () => { it('transformArguments', () => { assert.deepEqual( - MIN.transformArguments('key'), + parseArgs(MIN, 'key'), ['TDIGEST.MIN', 'key'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/MIN.ts b/packages/bloom/lib/commands/t-digest/MIN.ts index 914998a1ec..cc44dbbea4 100644 --- a/packages/bloom/lib/commands/t-digest/MIN.ts +++ b/packages/bloom/lib/commands/t-digest/MIN.ts @@ -1,11 +1,12 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TDIGEST.MIN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TDIGEST.MIN'); + parser.pushKey(key); }, transformReply: transformDoubleReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/QUANTILE.spec.ts b/packages/bloom/lib/commands/t-digest/QUANTILE.spec.ts index c427f8c450..ac7249d12d 100644 --- a/packages/bloom/lib/commands/t-digest/QUANTILE.spec.ts +++ b/packages/bloom/lib/commands/t-digest/QUANTILE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import QUANTILE from './QUANTILE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.QUANTILE', () => { it('transformArguments', () => { assert.deepEqual( - QUANTILE.transformArguments('key', [1, 2]), + parseArgs(QUANTILE, 'key', [1, 2]), ['TDIGEST.QUANTILE', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/QUANTILE.ts b/packages/bloom/lib/commands/t-digest/QUANTILE.ts index f7057a37d1..962c3a9b4c 100644 --- a/packages/bloom/lib/commands/t-digest/QUANTILE.ts +++ b/packages/bloom/lib/commands/t-digest/QUANTILE.ts @@ -1,17 +1,16 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleArrayReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, quantiles: Array) { - const args = ['TDIGEST.QUANTILE', key]; + parseCommand(parser: CommandParser, key: RedisArgument, quantiles: Array) { + parser.push('TDIGEST.QUANTILE'); + parser.pushKey(key); for (const quantile of quantiles) { - args.push(quantile.toString()); + parser.push(quantile.toString()); } - - return args; }, transformReply: transformDoubleArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/RANK.spec.ts b/packages/bloom/lib/commands/t-digest/RANK.spec.ts index dcdae48cb0..f1747662f0 100644 --- a/packages/bloom/lib/commands/t-digest/RANK.spec.ts +++ b/packages/bloom/lib/commands/t-digest/RANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import RANK from './RANK'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.RANK', () => { it('transformArguments', () => { assert.deepEqual( - RANK.transformArguments('key', [1, 2]), + parseArgs(RANK, 'key', [1, 2]), ['TDIGEST.RANK', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/RANK.ts b/packages/bloom/lib/commands/t-digest/RANK.ts index 8c18ad1277..316ca74b54 100644 --- a/packages/bloom/lib/commands/t-digest/RANK.ts +++ b/packages/bloom/lib/commands/t-digest/RANK.ts @@ -1,22 +1,23 @@ -import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/lib/RESP/types'; export function transformRankArguments( - command: RedisArgument, + parser: CommandParser, key: RedisArgument, values: Array ) { - const args = [command, key]; + parser.pushKey(key); for (const value of values) { - args.push(value.toString()); + parser.push(value.toString()); } - - return args; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: transformRankArguments.bind(undefined, 'TDIGEST.RANK'), + parseCommand(...args: Parameters) { + args[0].push('TDIGEST.RANK'); + transformRankArguments(...args); + }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/RESET.spec.ts b/packages/bloom/lib/commands/t-digest/RESET.spec.ts index 072257113b..8e1fc12e6e 100644 --- a/packages/bloom/lib/commands/t-digest/RESET.spec.ts +++ b/packages/bloom/lib/commands/t-digest/RESET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import RESET from './RESET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.RESET', () => { it('transformArguments', () => { assert.deepEqual( - RESET.transformArguments('key'), + parseArgs(RESET, 'key'), ['TDIGEST.RESET', 'key'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/RESET.ts b/packages/bloom/lib/commands/t-digest/RESET.ts index 372a1efd48..571102bfc2 100644 --- a/packages/bloom/lib/commands/t-digest/RESET.ts +++ b/packages/bloom/lib/commands/t-digest/RESET.ts @@ -1,10 +1,11 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument) { - return ['TDIGEST.RESET', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TDIGEST.RESET'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/REVRANK.spec.ts b/packages/bloom/lib/commands/t-digest/REVRANK.spec.ts index baa1b94afa..be7b23b223 100644 --- a/packages/bloom/lib/commands/t-digest/REVRANK.spec.ts +++ b/packages/bloom/lib/commands/t-digest/REVRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import REVRANK from './REVRANK'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.REVRANK', () => { it('transformArguments', () => { assert.deepEqual( - REVRANK.transformArguments('key', [1, 2]), + parseArgs(REVRANK, 'key', [1, 2]), ['TDIGEST.REVRANK', 'key', '1', '2'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/REVRANK.ts b/packages/bloom/lib/commands/t-digest/REVRANK.ts index 456b2be5a3..ca9301bb42 100644 --- a/packages/bloom/lib/commands/t-digest/REVRANK.ts +++ b/packages/bloom/lib/commands/t-digest/REVRANK.ts @@ -1,9 +1,11 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import RANK, { transformRankArguments } from './RANK'; export default { - FIRST_KEY_INDEX: RANK.FIRST_KEY_INDEX, IS_READ_ONLY: RANK.IS_READ_ONLY, - transformArguments: transformRankArguments.bind(undefined, 'TDIGEST.REVRANK'), + parseCommand(...args: Parameters) { + args[0].push('TDIGEST.REVRANK'); + transformRankArguments(...args); + }, transformReply: RANK.transformReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.spec.ts b/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.spec.ts index c43c0f4755..8e83c73647 100644 --- a/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.spec.ts +++ b/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import TRIMMED_MEAN from './TRIMMED_MEAN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TDIGEST.TRIMMED_MEAN', () => { it('transformArguments', () => { assert.deepEqual( - TRIMMED_MEAN.transformArguments('key', 0, 1), + parseArgs(TRIMMED_MEAN, 'key', 0, 1), ['TDIGEST.TRIMMED_MEAN', 'key', '0', '1'] ); }); diff --git a/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.ts b/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.ts index f91dd7d809..f411198260 100644 --- a/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.ts +++ b/packages/bloom/lib/commands/t-digest/TRIMMED_MEAN.ts @@ -1,20 +1,18 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, lowCutPercentile: number, highCutPercentile: number ) { - return [ - 'TDIGEST.TRIMMED_MEAN', - key, - lowCutPercentile.toString(), - highCutPercentile.toString() - ]; + parser.push('TDIGEST.TRIMMED_MEAN'); + parser.pushKey(key); + parser.push(lowCutPercentile.toString(), highCutPercentile.toString()); }, transformReply: transformDoubleReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/t-digest/index.ts b/packages/bloom/lib/commands/t-digest/index.ts index d180911dbf..fb80b35d0a 100644 --- a/packages/bloom/lib/commands/t-digest/index.ts +++ b/packages/bloom/lib/commands/t-digest/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands } from '@redis/client/lib/RESP/types'; import ADD from './ADD'; import BYRANK from './BYRANK'; import BYREVRANK from './BYREVRANK'; diff --git a/packages/bloom/lib/commands/top-k/ADD.spec.ts b/packages/bloom/lib/commands/top-k/ADD.spec.ts index 8f6f9300b3..15a7a9ce1d 100644 --- a/packages/bloom/lib/commands/top-k/ADD.spec.ts +++ b/packages/bloom/lib/commands/top-k/ADD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import ADD from './ADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.ADD', () => { it('transformArguments', () => { assert.deepEqual( - ADD.transformArguments('key', 'item'), + parseArgs(ADD, 'key', 'item'), ['TOPK.ADD', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/top-k/ADD.ts b/packages/bloom/lib/commands/top-k/ADD.ts index 99982cc8e6..42b162165c 100644 --- a/packages/bloom/lib/commands/top-k/ADD.ts +++ b/packages/bloom/lib/commands/top-k/ADD.ts @@ -1,11 +1,13 @@ -import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['TOPK.ADD', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('TOPK.ADD'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/COUNT.spec.ts b/packages/bloom/lib/commands/top-k/COUNT.spec.ts index dce03f0e78..a242edfef8 100644 --- a/packages/bloom/lib/commands/top-k/COUNT.spec.ts +++ b/packages/bloom/lib/commands/top-k/COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import COUNT from './COUNT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.COUNT', () => { it('transformArguments', () => { assert.deepEqual( - COUNT.transformArguments('key', 'item'), + parseArgs(COUNT, 'key', 'item'), ['TOPK.COUNT', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/top-k/COUNT.ts b/packages/bloom/lib/commands/top-k/COUNT.ts index 7e3ccc6dc4..7cca009c59 100644 --- a/packages/bloom/lib/commands/top-k/COUNT.ts +++ b/packages/bloom/lib/commands/top-k/COUNT.ts @@ -1,11 +1,13 @@ -import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['TOPK.COUNT', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('TOPK.COUNT'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/INCRBY.spec.ts b/packages/bloom/lib/commands/top-k/INCRBY.spec.ts index aa7032a9a0..94e5b1d705 100644 --- a/packages/bloom/lib/commands/top-k/INCRBY.spec.ts +++ b/packages/bloom/lib/commands/top-k/INCRBY.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INCRBY from './INCRBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.INCRBY', () => { describe('transformArguments', () => { it('single item', () => { assert.deepEqual( - INCRBY.transformArguments('key', { + parseArgs(INCRBY, 'key', { item: 'item', incrementBy: 1 }), @@ -16,7 +17,7 @@ describe('TOPK.INCRBY', () => { it('multiple items', () => { assert.deepEqual( - INCRBY.transformArguments('key', [{ + parseArgs(INCRBY, 'key', [{ item: 'a', incrementBy: 1 }, { diff --git a/packages/bloom/lib/commands/top-k/INCRBY.ts b/packages/bloom/lib/commands/top-k/INCRBY.ts index 16decf44dc..52ea0edc96 100644 --- a/packages/bloom/lib/commands/top-k/INCRBY.ts +++ b/packages/bloom/lib/commands/top-k/INCRBY.ts @@ -1,32 +1,32 @@ -import { RedisArgument, ArrayReply, SimpleStringReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, SimpleStringReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export interface TopKIncrByItem { item: string; incrementBy: number; } -function pushIncrByItem(args: Array, { item, incrementBy }: TopKIncrByItem) { - args.push(item, incrementBy.toString()); +function pushIncrByItem(parser: CommandParser, { item, incrementBy }: TopKIncrByItem) { + parser.push(item, incrementBy.toString()); } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, items: TopKIncrByItem | Array ) { - const args = ['TOPK.INCRBY', key]; + parser.push('TOPK.INCRBY'); + parser.pushKey(key); if (Array.isArray(items)) { for (const item of items) { - pushIncrByItem(args, item); + pushIncrByItem(parser, item); } } else { - pushIncrByItem(args, items); + pushIncrByItem(parser, items); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/INFO.spec.ts b/packages/bloom/lib/commands/top-k/INFO.spec.ts index 8e17829a2a..2efbf0bdbe 100644 --- a/packages/bloom/lib/commands/top-k/INFO.spec.ts +++ b/packages/bloom/lib/commands/top-k/INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import INFO from './INFO'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('key'), + parseArgs(INFO, 'key'), ['TOPK.INFO', 'key'] ); }); diff --git a/packages/bloom/lib/commands/top-k/INFO.ts b/packages/bloom/lib/commands/top-k/INFO.ts index e6f55ac2c1..89ebeaa8eb 100644 --- a/packages/bloom/lib/commands/top-k/INFO.ts +++ b/packages/bloom/lib/commands/top-k/INFO.ts @@ -1,5 +1,6 @@ -import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; -import { RedisArgument, TuplesToMapReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command, SimpleStringReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, TuplesToMapReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command, SimpleStringReply, TypeMapping } from '@redis/client/lib/RESP/types'; +import { transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; import { transformInfoV2Reply } from '../bloom'; export type TopKInfoReplyMap = TuplesToMapReply<[ @@ -10,10 +11,10 @@ export type TopKInfoReplyMap = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TOPK.INFO', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TOPK.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping): TopKInfoReplyMap => { diff --git a/packages/bloom/lib/commands/top-k/LIST.spec.ts b/packages/bloom/lib/commands/top-k/LIST.spec.ts index 7ab96182bb..8f5d0efa4d 100644 --- a/packages/bloom/lib/commands/top-k/LIST.spec.ts +++ b/packages/bloom/lib/commands/top-k/LIST.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import LIST from './LIST'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.LIST', () => { it('transformArguments', () => { assert.deepEqual( - LIST.transformArguments('key'), + parseArgs(LIST, 'key'), ['TOPK.LIST', 'key'] ); }); diff --git a/packages/bloom/lib/commands/top-k/LIST.ts b/packages/bloom/lib/commands/top-k/LIST.ts index 26345b7246..74b85e0f71 100644 --- a/packages/bloom/lib/commands/top-k/LIST.ts +++ b/packages/bloom/lib/commands/top-k/LIST.ts @@ -1,10 +1,11 @@ -import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TOPK.LIST', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TOPK.LIST'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.spec.ts b/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.spec.ts index 862d17eb3e..852170e8cd 100644 --- a/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.spec.ts +++ b/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import LIST_WITHCOUNT from './LIST_WITHCOUNT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.LIST WITHCOUNT', () => { testUtils.isVersionGreaterThanHook([2, 2, 9]); it('transformArguments', () => { assert.deepEqual( - LIST_WITHCOUNT.transformArguments('key'), + parseArgs(LIST_WITHCOUNT, 'key'), ['TOPK.LIST', 'key', 'WITHCOUNT'] ); }); diff --git a/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.ts b/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.ts index d26936fd3c..a3a3d3f43f 100644 --- a/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.ts +++ b/packages/bloom/lib/commands/top-k/LIST_WITHCOUNT.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, BlobStringReply, NumberReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, NumberReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TOPK.LIST', key, 'WITHCOUNT']; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TOPK.LIST'); + parser.pushKey(key); + parser.push('WITHCOUNT'); }, transformReply(rawReply: UnwrapReply>) { const reply: Array<{ diff --git a/packages/bloom/lib/commands/top-k/QUERY.spec.ts b/packages/bloom/lib/commands/top-k/QUERY.spec.ts index d5ecfebb6c..3651ec5d37 100644 --- a/packages/bloom/lib/commands/top-k/QUERY.spec.ts +++ b/packages/bloom/lib/commands/top-k/QUERY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import QUERY from './QUERY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.QUERY', () => { it('transformArguments', () => { assert.deepEqual( - QUERY.transformArguments('key', 'item'), + parseArgs(QUERY, 'key', 'item'), ['TOPK.QUERY', 'key', 'item'] ); }); diff --git a/packages/bloom/lib/commands/top-k/QUERY.ts b/packages/bloom/lib/commands/top-k/QUERY.ts index 5529d4ab83..49b9171437 100644 --- a/packages/bloom/lib/commands/top-k/QUERY.ts +++ b/packages/bloom/lib/commands/top-k/QUERY.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments, transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument, transformBooleanArrayReply } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, items: RedisVariadicArgument) { - return pushVariadicArguments(['TOPK.QUERY', key], items); + parseCommand(parser: CommandParser, key: RedisArgument, items: RedisVariadicArgument) { + parser.push('TOPK.QUERY'); + parser.pushKey(key); + parser.pushVariadic(items); }, transformReply: transformBooleanArrayReply } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/RESERVE.spec.ts b/packages/bloom/lib/commands/top-k/RESERVE.spec.ts index 39d8fb7efc..aa8d194f94 100644 --- a/packages/bloom/lib/commands/top-k/RESERVE.spec.ts +++ b/packages/bloom/lib/commands/top-k/RESERVE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../../test-utils'; import RESERVE from './RESERVE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TOPK.RESERVE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - RESERVE.transformArguments('topK', 3), + parseArgs(RESERVE, 'topK', 3), ['TOPK.RESERVE', 'topK', '3'] ); }); it('with options', () => { assert.deepEqual( - RESERVE.transformArguments('topK', 3, { + parseArgs(RESERVE, 'topK', 3, { width: 8, depth: 7, decay: 0.9 diff --git a/packages/bloom/lib/commands/top-k/RESERVE.ts b/packages/bloom/lib/commands/top-k/RESERVE.ts index 12671728fe..f3ef3bf720 100644 --- a/packages/bloom/lib/commands/top-k/RESERVE.ts +++ b/packages/bloom/lib/commands/top-k/RESERVE.ts @@ -1,4 +1,5 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; export interface TopKReserveOptions { width: number; @@ -7,20 +8,19 @@ export interface TopKReserveOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, topK: number, options?: TopKReserveOptions) { - const args = ['TOPK.RESERVE', key, topK.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, topK: number, options?: TopKReserveOptions) { + parser.push('TOPK.RESERVE'); + parser.pushKey(key); + parser.push(topK.toString()); if (options) { - args.push( + parser.push( options.width.toString(), options.depth.toString(), options.decay.toString() ); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/bloom/lib/commands/top-k/index.ts b/packages/bloom/lib/commands/top-k/index.ts index fb5de543ca..0352745fd0 100644 --- a/packages/bloom/lib/commands/top-k/index.ts +++ b/packages/bloom/lib/commands/top-k/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands } from '@redis/client/lib/RESP/types'; import ADD from './ADD'; import COUNT from './COUNT'; import INCRBY from './INCRBY'; diff --git a/packages/client/lib/RESP/encoder.ts b/packages/client/lib/RESP/encoder.ts index af857711dc..995650627f 100644 --- a/packages/client/lib/RESP/encoder.ts +++ b/packages/client/lib/RESP/encoder.ts @@ -2,7 +2,7 @@ import { RedisArgument } from './types'; const CRLF = '\r\n'; -export default function encodeCommand(args: Array): Array { +export default function encodeCommand(args: ReadonlyArray): ReadonlyArray { const toWrite: Array = []; let strings = '*' + args.length + CRLF; diff --git a/packages/client/lib/RESP/types.ts b/packages/client/lib/RESP/types.ts index 46fcd7ac8c..692c433a49 100644 --- a/packages/client/lib/RESP/types.ts +++ b/packages/client/lib/RESP/types.ts @@ -1,3 +1,5 @@ +import { CommandParser } from '../client/parser'; +import { Tail } from '../commands/generic-transformers'; import { BlobError, SimpleError } from '../errors'; import { RedisScriptConfig, SHA1 } from '../lua-script'; import { RESP_TYPES } from './decoder'; @@ -272,15 +274,16 @@ export type CommandArguments = Array & { preserve?: unknown }; // }; export type Command = { - FIRST_KEY_INDEX?: number | ((this: void, ...args: Array) => RedisArgument | undefined); + CACHEABLE?: boolean; IS_READ_ONLY?: boolean; /** * @internal * TODO: remove once `POLICIES` is implemented */ IS_FORWARD_COMMAND?: boolean; + NOT_KEYED_COMMAND?: true; // POLICIES?: CommandPolicies; - transformArguments(this: void, ...args: Array): CommandArguments; + parseCommand(this: void, parser: CommandParser, ...args: Array): void; TRANSFORM_LEGACY_REPLY?: boolean; transformReply: TransformReply | Record; unstableResp3?: boolean; @@ -365,7 +368,7 @@ export type CommandSignature< COMMAND extends Command, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping -> = (...args: Parameters) => Promise, TYPE_MAPPING>>; +> = (...args: Tail>) => Promise, TYPE_MAPPING>>; // export type CommandWithPoliciesSignature< // COMMAND extends Command, diff --git a/packages/client/lib/client/commands-queue.ts b/packages/client/lib/client/commands-queue.ts index a4029779fc..15e8a747b9 100644 --- a/packages/client/lib/client/commands-queue.ts +++ b/packages/client/lib/client/commands-queue.ts @@ -1,7 +1,7 @@ import { SinglyLinkedList, DoublyLinkedNode, DoublyLinkedList } from './linked-list'; import encodeCommand from '../RESP/encoder'; import { Decoder, PUSH_TYPE_MAPPING, RESP_TYPES } from '../RESP/decoder'; -import { CommandArguments, TypeMapping, ReplyUnion, RespVersions } from '../RESP/types'; +import { TypeMapping, ReplyUnion, RespVersions, RedisArgument } from '../RESP/types'; import { ChannelListeners, PubSub, PubSubCommand, PubSubListener, PubSubType, PubSubTypeListeners } from './pub-sub'; import { AbortError, ErrorReply } from '../errors'; import { MonitorCallback } from '.'; @@ -17,7 +17,7 @@ export interface CommandOptions { } export interface CommandToWrite extends CommandWaitingForReply { - args: CommandArguments; + args: ReadonlyArray; chainId: symbol | undefined; abort: { signal: AbortSignal; @@ -117,7 +117,7 @@ export default class RedisCommandsQueue { } addCommand( - args: CommandArguments, + args: ReadonlyArray, options?: CommandOptions ): Promise { if (this.#maxLength && this.#toWrite.length + this.#waitingForReply.length >= this.#maxLength) { @@ -346,7 +346,7 @@ export default class RedisCommandsQueue { *commandsToWrite() { let toSend = this.#toWrite.shift(); while (toSend) { - let encoded: CommandArguments; + let encoded: ReadonlyArray try { encoded = encodeCommand(toSend.args); } catch (err) { diff --git a/packages/client/lib/client/index.spec.ts b/packages/client/lib/client/index.spec.ts index 50ed3d39da..cd2040ec97 100644 --- a/packages/client/lib/client/index.spec.ts +++ b/packages/client/lib/client/index.spec.ts @@ -9,6 +9,7 @@ import { MATH_FUNCTION, loadMathFunction } from '../commands/FUNCTION_LOAD.spec' import { RESP_TYPES } from '../RESP/decoder'; import { BlobStringReply, NumberReply } from '../RESP/types'; import { SortedSetMember } from '../commands/generic-transformers'; +import { CommandParser } from './parser'; export const SQUARE_SCRIPT = defineScript({ SCRIPT: @@ -16,8 +17,8 @@ export const SQUARE_SCRIPT = defineScript({ return number * number`, NUMBER_OF_KEYS: 1, FIRST_KEY_INDEX: 0, - transformArguments(key: string) { - return [key]; + parseCommand(parser: CommandParser, key: string) { + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply }); @@ -318,8 +319,8 @@ describe('Client', () => { const module = { echo: { - transformArguments(message: string) { - return ['ECHO', message]; + parseCommand(parser: CommandParser, message: string) { + parser.push('ECHO', message); }, transformReply: undefined as unknown as () => BlobStringReply } diff --git a/packages/client/lib/client/index.ts b/packages/client/lib/client/index.ts index 64a3b57881..55355a133d 100644 --- a/packages/client/lib/client/index.ts +++ b/packages/client/lib/client/index.ts @@ -7,14 +7,15 @@ import { ClientClosedError, ClientOfflineError, DisconnectsClientError, WatchErr import { URL } from 'node:url'; import { TcpSocketConnectOpts } from 'node:net'; import { PUBSUB_TYPE, PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub'; -import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply } from '../RESP/types'; +import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply } from '../RESP/types'; import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command'; import { RedisMultiQueuedCommand } from '../multi-command'; import HELLO, { HelloOptions } from '../commands/HELLO'; import { ScanOptions, ScanCommonOptions } from '../commands/SCAN'; import { RedisLegacyClient, RedisLegacyClientType } from './legacy-mode'; import { RedisPoolOptions, RedisClientPool } from './pool'; -import { RedisVariadicArgument, pushVariadicArguments } from '../commands/generic-transformers'; +import { RedisVariadicArgument, parseArgs, pushVariadicArguments } from '../commands/generic-transformers'; +import { BasicCommandParser, CommandParser } from './parser'; export interface RedisClientOptions< M extends RedisModules = RedisModules, @@ -151,64 +152,50 @@ export default class RedisClient< > extends EventEmitter { static #createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); - return async function (this: ProxyClient, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._commandOptions?.typeMapping; - const reply = await this.sendCommand(redisArgs, this._commandOptions); + return async function (this: ProxyClient, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; - }; + return this._self._executeCommand(command, parser, this._commandOptions, transformReply); + } } static #createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); - return async function (this: NamespaceProxyClient, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._self._commandOptions?.typeMapping - const reply = await this._self.sendCommand(redisArgs, this._self._commandOptions); + return async function (this: NamespaceProxyClient, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; + return this._self._executeCommand(command, parser, this._self._commandOptions, transformReply); }; } static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); - return async function (this: NamespaceProxyClient, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const typeMapping = this._self._commandOptions?.typeMapping; + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); - const reply = await this._self.sendCommand( - prefix.concat(fnArgs), - this._self._commandOptions - ); + return async function (this: NamespaceProxyClient, ...args: Array) { + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, fnArgs.preserve, typeMapping) : - reply; + return this._self._executeCommand(fn, parser, this._self._commandOptions, transformReply); }; } static #createScriptCommand(script: RedisScript, resp: RespVersions) { - const prefix = scriptArgumentsPrefix(script), - transformReply = getTransformReply(script, resp); + const prefix = scriptArgumentsPrefix(script); + const transformReply = getTransformReply(script, resp); + return async function (this: ProxyClient, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - const redisArgs = prefix.concat(scriptArgs); - const typeMapping = this._commandOptions?.typeMapping; - - const reply = await this.executeScript(script, redisArgs, this._commandOptions); - - return transformReply ? - transformReply(reply, scriptArgs.preserve, typeMapping) : - reply; - }; + const parser = new BasicCommandParser(); + parser.push(...prefix); + script.parseCommand(parser, ...args) + + return this._executeScript(script, parser, this._commandOptions, transformReply); + } } static factory< @@ -376,12 +363,12 @@ export default class RedisClient< } commands.push( - HELLO.transformArguments(this.#options.RESP, hello) + parseArgs(HELLO, this.#options.RESP, hello) ); } else { if (this.#options?.username || this.#options?.password) { commands.push( - COMMANDS.AUTH.transformArguments({ + parseArgs(COMMANDS.AUTH, { username: this.#options.username, password: this.#options.password ?? '' }) @@ -390,7 +377,7 @@ export default class RedisClient< if (this.#options?.name) { commands.push( - COMMANDS.CLIENT_SETNAME.transformArguments(this.#options.name) + parseArgs(COMMANDS.CLIENT_SETNAME, this.#options.name) ); } } @@ -401,7 +388,7 @@ export default class RedisClient< if (this.#options?.readonly) { commands.push( - COMMANDS.READONLY.transformArguments() + parseArgs(COMMANDS.READONLY) ); } @@ -585,35 +572,64 @@ export default class RedisClient< return this as unknown as RedisClientType; } - sendCommand( - args: Array, - options?: CommandOptions - ): Promise { - if (!this._self.#socket.isOpen) { - return Promise.reject(new ClientClosedError()); - } else if (!this._self.#socket.isReady && this._self.#options?.disableOfflineQueue) { - return Promise.reject(new ClientOfflineError()); + /** + * @internal + */ + async _executeCommand( + command: Command, + parser: CommandParser, + commandOptions: CommandOptions | undefined, + transformReply: TransformReply | undefined, + ) { + const reply = await this.sendCommand(parser.redisArgs, commandOptions); + + if (transformReply) { + return transformReply(reply, parser.preserve, commandOptions?.typeMapping); } - const promise = this._self.#queue.addCommand(args, options); - this._self.#scheduleWrite(); - return promise; + return reply; } - async executeScript( + /** + * @internal + */ + async _executeScript( script: RedisScript, - args: Array, - options?: CommandOptions + parser: CommandParser, + options: CommandOptions | undefined, + transformReply: TransformReply | undefined, ) { + const args = parser.redisArgs as Array; + + let reply: ReplyUnion; try { - return await this.sendCommand(args, options); + reply = await this.sendCommand(args, options); } catch (err) { if (!(err as Error)?.message?.startsWith?.('NOSCRIPT')) throw err; args[0] = 'EVAL'; args[1] = script.SCRIPT; - return await this.sendCommand(args, options); + reply = await this.sendCommand(args, options); + } + + return transformReply ? + transformReply(reply, parser.preserve, options?.typeMapping) : + reply; + } + + sendCommand( + args: ReadonlyArray, + options?: CommandOptions + ): Promise { + if (!this._self.#socket.isOpen) { + return Promise.reject(new ClientClosedError()); + } else if (!this._self.#socket.isReady && this._self.#options?.disableOfflineQueue) { + return Promise.reject(new ClientOfflineError()); } + + const promise = this._self.#queue.addCommand(args, options); + this._self.#scheduleWrite(); + return promise; } async SELECT(db: number): Promise { diff --git a/packages/client/lib/client/multi-command.ts b/packages/client/lib/client/multi-command.ts index b6579fcf9b..a687655b60 100644 --- a/packages/client/lib/client/multi-command.ts +++ b/packages/client/lib/client/multi-command.ts @@ -2,6 +2,8 @@ import COMMANDS from '../commands'; import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command'; import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types'; import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander'; +import { BasicCommandParser } from './parser'; +import { Tail } from '../commands/generic-transformers'; type CommandSignature< REPLIES extends Array, @@ -11,7 +13,7 @@ type CommandSignature< S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping -> = (...args: Parameters) => RedisClientMultiCommandType< +> = (...args: Tail>) => RedisClientMultiCommandType< [...REPLIES, ReplyWithTypeMapping, TYPE_MAPPING>], M, F, @@ -88,9 +90,16 @@ type ExecuteMulti = (commands: Array, selectedDB?: numb export default class RedisClientMultiCommand { static #createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: RedisClientMultiCommand, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this.addCommand( - command.transformArguments(...args), + redisArgs, transformReply ); }; @@ -98,21 +107,33 @@ export default class RedisClientMultiCommand { static #createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: { _self: RedisClientMultiCommand }, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this._self.addCommand( - command.transformArguments(...args), + redisArgs, transformReply ); }; } static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); + return function (this: { _self: RedisClientMultiCommand }, ...args: Array) { - const fnArgs = fn.transformArguments(...args), - redisArgs: CommandArguments = prefix.concat(fnArgs); - redisArgs.preserve = fnArgs.preserve; + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this._self.addCommand( redisArgs, transformReply @@ -122,13 +143,19 @@ export default class RedisClientMultiCommand { static #createScriptCommand(script: RedisScript, resp: RespVersions) { const transformReply = getTransformReply(script, resp); + return function (this: RedisClientMultiCommand, ...args: Array) { - this.#multi.addScript( + const parser = new BasicCommandParser(); + script.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + + return this.#addScript( script, - script.transformArguments(...args), + redisArgs, transformReply ); - return this; }; } @@ -149,17 +176,16 @@ export default class RedisClientMultiCommand { }); } - readonly #multi = new RedisMultiCommand(); + readonly #multi: RedisMultiCommand readonly #executeMulti: ExecuteMulti; readonly #executePipeline: ExecuteMulti; - readonly #typeMapping?: TypeMapping; #selectedDB?: number; constructor(executeMulti: ExecuteMulti, executePipeline: ExecuteMulti, typeMapping?: TypeMapping) { + this.#multi = new RedisMultiCommand(typeMapping); this.#executeMulti = executeMulti; this.#executePipeline = executePipeline; - this.#typeMapping = typeMapping; } SELECT(db: number, transformReply?: TransformReply): this { @@ -175,12 +201,21 @@ export default class RedisClientMultiCommand { return this; } + #addScript( + script: RedisScript, + args: CommandArguments, + transformReply?: TransformReply + ) { + this.#multi.addScript(script, args, transformReply); + + return this; + } + async exec(execAsPipeline = false): Promise> { if (execAsPipeline) return this.execAsPipeline(); return this.#multi.transformReplies( - await this.#executeMulti(this.#multi.queue, this.#selectedDB), - this.#typeMapping + await this.#executeMulti(this.#multi.queue, this.#selectedDB) ) as MultiReplyType; } @@ -194,8 +229,7 @@ export default class RedisClientMultiCommand { if (this.#multi.queue.length === 0) return [] as MultiReplyType; return this.#multi.transformReplies( - await this.#executePipeline(this.#multi.queue, this.#selectedDB), - this.#typeMapping + await this.#executePipeline(this.#multi.queue, this.#selectedDB) ) as MultiReplyType; } diff --git a/packages/client/lib/client/parser.ts b/packages/client/lib/client/parser.ts new file mode 100644 index 0000000000..12eec45773 --- /dev/null +++ b/packages/client/lib/client/parser.ts @@ -0,0 +1,92 @@ +import { RedisArgument } from '../RESP/types'; +import { RedisVariadicArgument } from '../commands/generic-transformers'; + +export interface CommandParser { + redisArgs: ReadonlyArray; + keys: ReadonlyArray; + firstKey: RedisArgument | undefined; + preserve: unknown; + + push: (...arg: Array) => unknown; + pushVariadic: (vals: RedisVariadicArgument) => unknown; + pushVariadicWithLength: (vals: RedisVariadicArgument) => unknown; + pushVariadicNumber: (vals: number | Array) => unknown; + pushKey: (key: RedisArgument) => unknown; // normal push of keys + pushKeys: (keys: RedisVariadicArgument) => unknown; // push multiple keys at a time + pushKeysLength: (keys: RedisVariadicArgument) => unknown; // push multiple keys at a time +} + +export class BasicCommandParser implements CommandParser { + #redisArgs: Array = []; + #keys: Array = []; + preserve: unknown; + + get redisArgs() { + return this.#redisArgs; + } + + get keys() { + return this.#keys; + } + + get firstKey() { + return this.#keys[0]; + } + + push(...arg: Array) { + this.#redisArgs.push(...arg); + }; + + pushVariadic(vals: RedisVariadicArgument) { + if (Array.isArray(vals)) { + for (const val of vals) { + this.push(val); + } + } else { + this.push(vals); + } + } + + pushVariadicWithLength(vals: RedisVariadicArgument) { + if (Array.isArray(vals)) { + this.#redisArgs.push(vals.length.toString()); + } else { + this.#redisArgs.push('1'); + } + this.pushVariadic(vals); + } + + pushVariadicNumber(vals: number | number[]) { + if (Array.isArray(vals)) { + for (const val of vals) { + this.push(val.toString()); + } + } else { + this.push(vals.toString()); + } + } + + pushKey(key: RedisArgument) { + this.#keys.push(key); + this.#redisArgs.push(key); + } + + pushKeysLength(keys: RedisVariadicArgument) { + if (Array.isArray(keys)) { + this.#redisArgs.push(keys.length.toString()); + } else { + this.#redisArgs.push('1'); + } + this.pushKeys(keys); + } + + pushKeys(keys: RedisVariadicArgument) { + if (Array.isArray(keys)) { + this.#keys.push(...keys); + this.#redisArgs.push(...keys); + } else { + this.#keys.push(keys); + this.#redisArgs.push(keys); + } + } +} diff --git a/packages/client/lib/client/pool.ts b/packages/client/lib/client/pool.ts index 4bd99ece8b..a08377e3d3 100644 --- a/packages/client/lib/client/pool.ts +++ b/packages/client/lib/client/pool.ts @@ -7,6 +7,7 @@ import { TimeoutError } from '../errors'; import { attachConfig, functionArgumentsPrefix, getTransformReply, scriptArgumentsPrefix } from '../commander'; import { CommandOptions } from './commands-queue'; import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command'; +import { BasicCommandParser } from './parser'; export interface RedisPoolOptions { /** @@ -64,63 +65,48 @@ export class RedisClientPool< > extends EventEmitter { static #createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); - return async function (this: ProxyPool, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._commandOptions?.typeMapping; - const reply = await this.sendCommand(redisArgs, this._commandOptions); + return async function (this: ProxyPool, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; + return this.execute(client => client._executeCommand(command, parser, this._commandOptions, transformReply)) }; } static #createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); - return async function (this: NamespaceProxyPool, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._self._commandOptions?.typeMapping; - const reply = await this._self.sendCommand(redisArgs, this._self._commandOptions); + return async function (this: NamespaceProxyPool, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; + return this._self.execute(client => client._executeCommand(command, parser, this._self._commandOptions, transformReply)) }; } static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); - return async function (this: NamespaceProxyPool, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const typeMapping = this._self._commandOptions?.typeMapping; + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); - const reply = await this._self.sendCommand( - prefix.concat(fnArgs), - this._self._commandOptions - ); + return async function (this: NamespaceProxyPool, ...args: Array) { + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); - return transformReply ? - transformReply(reply, fnArgs.preserve, typeMapping) : - reply; - }; + return this._self.execute(client => client._executeCommand(fn, parser, this._self._commandOptions, transformReply)) }; } static #createScriptCommand(script: RedisScript, resp: RespVersions) { - const prefix = scriptArgumentsPrefix(script), - transformReply = getTransformReply(script, resp); + const prefix = scriptArgumentsPrefix(script); + const transformReply = getTransformReply(script, resp); + return async function (this: ProxyPool, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - const redisArgs = prefix.concat(scriptArgs); - const typeMapping = this._commandOptions?.typeMapping; + const parser = new BasicCommandParser(); + parser.pushVariadic(prefix); + script.parseCommand(parser, ...args); - const reply = await this.executeScript(script, redisArgs, this._commandOptions); - - return transformReply ? - transformReply(reply, scriptArgs.preserve, typeMapping) : - reply; + return this.execute(client => client._executeScript(script, parser, this._commandOptions, transformReply)) }; } @@ -426,14 +412,6 @@ export class RedisClientPool< return this.execute(client => client.sendCommand(args, options)); } - executeScript( - script: RedisScript, - args: Array, - options?: CommandOptions - ) { - return this.execute(client => client.executeScript(script, args, options)); - } - MULTI() { type Multi = new (...args: ConstructorParameters) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>; return new ((this as any).Multi as Multi)( diff --git a/packages/client/lib/client/socket.ts b/packages/client/lib/client/socket.ts index 3c2666e106..36afa36c04 100644 --- a/packages/client/lib/client/socket.ts +++ b/packages/client/lib/client/socket.ts @@ -271,7 +271,7 @@ export default class RedisSocket extends EventEmitter { }); } - write(iterable: Iterable>) { + write(iterable: Iterable>) { if (!this.#socket) return; this.#socket.cork(); diff --git a/packages/client/lib/cluster/index.ts b/packages/client/lib/cluster/index.ts index 7d01b1a20f..12928e71f1 100644 --- a/packages/client/lib/cluster/index.ts +++ b/packages/client/lib/cluster/index.ts @@ -9,6 +9,9 @@ import RedisClusterMultiCommand, { RedisClusterMultiCommandType } from './multi- import { PubSubListener } from '../client/pub-sub'; import { ErrorReply } from '../errors'; import { RedisTcpSocketOptions } from '../client/socket'; +import ASKING from '../commands/ASKING'; +import { BasicCommandParser } from '../client/parser'; +import { parseArgs } from '../commands/generic-transformers'; interface ClusterCommander< M extends RedisModules, @@ -69,7 +72,7 @@ export interface RedisClusterOptions< type ClusterCommand< NAME extends PropertyKey, COMMAND extends Command -> = COMMAND['FIRST_KEY_INDEX'] extends undefined ? ( +> = COMMAND['NOT_KEYED_COMMAND'] extends true ? ( COMMAND['IS_FORWARD_COMMAND'] extends true ? NAME : never ) : NAME; @@ -143,131 +146,70 @@ export default class RedisCluster< TYPE_MAPPING extends TypeMapping, // POLICIES extends CommandPolicies > extends EventEmitter { - static extractFirstKey( - command: C, - args: Parameters, - redisArgs: Array - ) { - let key: RedisArgument | undefined; - switch (typeof command.FIRST_KEY_INDEX) { - case 'number': - key = redisArgs[command.FIRST_KEY_INDEX]; - break; - - case 'function': - key = command.FIRST_KEY_INDEX(...args); - break; - } - - return key; - } - static #createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); return async function (this: ProxyCluster, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._commandOptions?.typeMapping; - - const firstKey = RedisCluster.extractFirstKey( - command, - args, - redisArgs - ); + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - const reply = await this.sendCommand( - firstKey, + return this._self.#execute( + parser.firstKey, command.IS_READ_ONLY, - redisArgs, this._commandOptions, - // command.POLICIES + (client, opts) => client._executeCommand(command, parser, opts, transformReply) ); - - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; }; } static #createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); - return async function (this: NamespaceProxyCluster, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._self._commandOptions?.typeMapping; - const firstKey = RedisCluster.extractFirstKey( - command, - args, - redisArgs - ); + return async function (this: NamespaceProxyCluster, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - const reply = await this._self.sendCommand( - firstKey, + return this._self.#execute( + parser.firstKey, command.IS_READ_ONLY, - redisArgs, this._self._commandOptions, - // command.POLICIES + (client, opts) => client._executeCommand(command, parser, opts, transformReply) ); - - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; }; } static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); + return async function (this: NamespaceProxyCluster, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const redisArgs = prefix.concat(fnArgs); - const typeMapping = this._self._commandOptions?.typeMapping; - - const firstKey = RedisCluster.extractFirstKey( - fn, - args, - fnArgs - ); + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); - const reply = await this._self.sendCommand( - firstKey, + return this._self.#execute( + parser.firstKey, fn.IS_READ_ONLY, - redisArgs, this._self._commandOptions, - // fn.POLICIES + (client, opts) => client._executeCommand(fn, parser, opts, transformReply) ); - - return transformReply ? - transformReply(reply, fnArgs.preserve, typeMapping) : - reply; }; } static #createScriptCommand(script: RedisScript, resp: RespVersions) { - const prefix = scriptArgumentsPrefix(script), - transformReply = getTransformReply(script, resp); + const prefix = scriptArgumentsPrefix(script); + const transformReply = getTransformReply(script, resp); + return async function (this: ProxyCluster, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - const redisArgs = prefix.concat(scriptArgs); - const typeMapping = this._commandOptions?.typeMapping; - - const firstKey = RedisCluster.extractFirstKey( - script, - args, - scriptArgs - ); + const parser = new BasicCommandParser(); + parser.push(...prefix); + script.parseCommand(parser, ...args); - const reply = await this.executeScript( - script, - firstKey, + return this._self.#execute( + parser.firstKey, script.IS_READ_ONLY, - redisArgs, this._commandOptions, - // script.POLICIES + (client, opts) => client._executeScript(script, parser, opts, transformReply) ); - - return transformReply ? - transformReply(reply, scriptArgs.preserve, typeMapping) : - reply; }; } @@ -443,15 +385,20 @@ export default class RedisCluster< async #execute( firstKey: RedisArgument | undefined, isReadonly: boolean | undefined, - fn: (client: RedisClientType) => Promise + options: ClusterCommandOptions | undefined, + fn: (client: RedisClientType, opts?: ClusterCommandOptions) => Promise ): Promise { const maxCommandRedirections = this.#options.maxCommandRedirections ?? 16; - let client = await this.#slots.getClient(firstKey, isReadonly), - i = 0; + let client = await this.#slots.getClient(firstKey, isReadonly); + let i = 0; + let myOpts = options; + while (true) { try { - return await fn(client); + return await fn(client, myOpts); } catch (err) { + // reset to passed in options, if changed by an ask request + myOpts = options; // TODO: error class if (++i > maxCommandRedirections || !(err instanceof Error)) { throw err; @@ -469,8 +416,14 @@ export default class RedisCluster< throw new Error(`Cannot find node ${address}`); } - await redirectTo.asking(); client = redirectTo; + + const chainId = Symbol('Asking Chain'); + myOpts = options ? {...options} : {}; + myOpts.chainId = chainId; + + client.sendCommand(parseArgs(ASKING), {chainId: chainId}).catch(err => { console.log(`Asking Failed: ${err}`) } ); + continue; } @@ -495,21 +448,8 @@ export default class RedisCluster< return this._self.#execute( firstKey, isReadonly, - client => client.sendCommand(args, options) - ); - } - - executeScript( - script: RedisScript, - firstKey: RedisArgument | undefined, - isReadonly: boolean | undefined, - args: Array, - options?: CommandOptions - ) { - return this._self.#execute( - firstKey, - isReadonly, - client => client.executeScript(script, args, options) + options, + (client, opts) => client.sendCommand(args, opts) ); } diff --git a/packages/client/lib/cluster/multi-command.ts b/packages/client/lib/cluster/multi-command.ts index 2b02e8d7df..f370618ff3 100644 --- a/packages/client/lib/cluster/multi-command.ts +++ b/packages/client/lib/cluster/multi-command.ts @@ -2,7 +2,8 @@ import COMMANDS from '../commands'; import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command'; import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping, RedisArgument } from '../RESP/types'; import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander'; -import RedisCluster from '.'; +import { BasicCommandParser } from '../client/parser'; +import { Tail } from '../commands/generic-transformers'; type CommandSignature< REPLIES extends Array, @@ -12,7 +13,7 @@ type CommandSignature< S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping -> = (...args: Parameters) => RedisClusterMultiCommandType< +> = (...args: Tail>) => RedisClusterMultiCommandType< [...REPLIES, ReplyWithTypeMapping, TYPE_MAPPING>], M, F, @@ -93,13 +94,15 @@ export type ClusterMultiExecute = ( export default class RedisClusterMultiCommand { static #createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: RedisClusterMultiCommand, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const firstKey = RedisCluster.extractFirstKey( - command, - args, - redisArgs - ); + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + const firstKey = parser.firstKey; + return this.addCommand( firstKey, command.IS_READ_ONLY, @@ -111,13 +114,15 @@ export default class RedisClusterMultiCommand { static #createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: { _self: RedisClusterMultiCommand }, ...args: Array) { - const redisArgs = command.transformArguments(...args), - firstKey = RedisCluster.extractFirstKey( - command, - args, - redisArgs - ); + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + const firstKey = parser.firstKey; + return this._self.addCommand( firstKey, command.IS_READ_ONLY, @@ -128,17 +133,18 @@ export default class RedisClusterMultiCommand { } static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); + return function (this: { _self: RedisClusterMultiCommand }, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const redisArgs: CommandArguments = prefix.concat(fnArgs); - const firstKey = RedisCluster.extractFirstKey( - fn, - args, - fnArgs - ); - redisArgs.preserve = fnArgs.preserve; + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + const firstKey = parser.firstKey; + return this._self.addCommand( firstKey, fn.IS_READ_ONLY, @@ -150,22 +156,22 @@ export default class RedisClusterMultiCommand { static #createScriptCommand(script: RedisScript, resp: RespVersions) { const transformReply = getTransformReply(script, resp); + return function (this: RedisClusterMultiCommand, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - this.#setState( - RedisCluster.extractFirstKey( - script, - args, - scriptArgs - ), - script.IS_READ_ONLY - ); - this.#multi.addScript( + const parser = new BasicCommandParser(); + script.parseCommand(parser, ...args); + + const scriptArgs: CommandArguments = parser.redisArgs; + scriptArgs.preserve = parser.preserve; + const firstKey = parser.firstKey; + + return this.#addScript( + firstKey, + script.IS_READ_ONLY, script, scriptArgs, transformReply ); - return this; }; } @@ -186,12 +192,12 @@ export default class RedisClusterMultiCommand { }); } - readonly #multi = new RedisMultiCommand(); + readonly #multi: RedisMultiCommand + readonly #executeMulti: ClusterMultiExecute; readonly #executePipeline: ClusterMultiExecute; #firstKey: RedisArgument | undefined; #isReadonly: boolean | undefined = true; - readonly #typeMapping?: TypeMapping; constructor( executeMulti: ClusterMultiExecute, @@ -199,10 +205,10 @@ export default class RedisClusterMultiCommand { routing: RedisArgument | undefined, typeMapping?: TypeMapping ) { + this.#multi = new RedisMultiCommand(typeMapping); this.#executeMulti = executeMulti; this.#executePipeline = executePipeline; this.#firstKey = routing; - this.#typeMapping = typeMapping; } #setState( @@ -224,6 +230,19 @@ export default class RedisClusterMultiCommand { return this; } + #addScript( + firstKey: RedisArgument | undefined, + isReadonly: boolean | undefined, + script: RedisScript, + args: CommandArguments, + transformReply?: TransformReply + ) { + this.#setState(firstKey, isReadonly); + this.#multi.addScript(script, args, transformReply); + + return this; + } + async exec(execAsPipeline = false) { if (execAsPipeline) return this.execAsPipeline(); @@ -232,8 +251,7 @@ export default class RedisClusterMultiCommand { this.#firstKey, this.#isReadonly, this.#multi.queue - ), - this.#typeMapping + ) ) as MultiReplyType; } @@ -251,8 +269,7 @@ export default class RedisClusterMultiCommand { this.#firstKey, this.#isReadonly, this.#multi.queue - ), - this.#typeMapping + ) ) as MultiReplyType; } diff --git a/packages/client/lib/commander.ts b/packages/client/lib/commander.ts index 4434317d26..6e5a2687cb 100644 --- a/packages/client/lib/commander.ts +++ b/packages/client/lib/commander.ts @@ -1,4 +1,4 @@ -import { Command, CommanderConfig, RedisCommands, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, RespVersions } from './RESP/types'; +import { Command, CommanderConfig, RedisArgument, RedisCommands, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, RespVersions, TransformReply } from './RESP/types'; interface AttachConfigOptions< M extends RedisModules, @@ -87,7 +87,7 @@ function attachNamespace(prototype: any, name: PropertyKey, fns: any) { }); } -export function getTransformReply(command: Command, resp: RespVersions) { +export function getTransformReply(command: Command, resp: RespVersions): TransformReply | undefined { switch (typeof command.transformReply) { case 'function': return command.transformReply; @@ -98,7 +98,7 @@ export function getTransformReply(command: Command, resp: RespVersions) { } export function functionArgumentsPrefix(name: string, fn: RedisFunction) { - const prefix: Array = [ + const prefix: Array = [ fn.IS_READ_ONLY ? 'FCALL_RO' : 'FCALL', name ]; diff --git a/packages/client/lib/commands/ACL_CAT.spec.ts b/packages/client/lib/commands/ACL_CAT.spec.ts index 2ce9d7db92..09d5ecade5 100644 --- a/packages/client/lib/commands/ACL_CAT.spec.ts +++ b/packages/client/lib/commands/ACL_CAT.spec.ts @@ -1,5 +1,6 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import ACL_CAT from './ACL_CAT'; describe('ACL CAT', () => { @@ -8,14 +9,14 @@ describe('ACL CAT', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ACL_CAT.transformArguments(), + parseArgs(ACL_CAT), ['ACL', 'CAT'] ); }); it('with categoryName', () => { assert.deepEqual( - ACL_CAT.transformArguments('dangerous'), + parseArgs(ACL_CAT, 'dangerous'), ['ACL', 'CAT', 'dangerous'] ); }); diff --git a/packages/client/lib/commands/ACL_CAT.ts b/packages/client/lib/commands/ACL_CAT.ts index dd4762239a..ae094b732b 100644 --- a/packages/client/lib/commands/ACL_CAT.ts +++ b/packages/client/lib/commands/ACL_CAT.ts @@ -1,16 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(categoryName?: RedisArgument) { - const args: Array = ['ACL', 'CAT']; - + parseCommand(parser: CommandParser, categoryName?: RedisArgument) { + parser.push('ACL', 'CAT'); if (categoryName) { - args.push(categoryName); + parser.push(categoryName); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_DELUSER.spec.ts b/packages/client/lib/commands/ACL_DELUSER.spec.ts index d6acbb2223..45fa3af9fc 100644 --- a/packages/client/lib/commands/ACL_DELUSER.spec.ts +++ b/packages/client/lib/commands/ACL_DELUSER.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_DELUSER from './ACL_DELUSER'; +import { parseArgs } from './generic-transformers'; describe('ACL DELUSER', () => { testUtils.isVersionGreaterThanHook([6]); @@ -8,14 +9,14 @@ describe('ACL DELUSER', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ACL_DELUSER.transformArguments('username'), + parseArgs(ACL_DELUSER, 'username'), ['ACL', 'DELUSER', 'username'] ); }); it('array', () => { assert.deepEqual( - ACL_DELUSER.transformArguments(['1', '2']), + parseArgs(ACL_DELUSER, ['1', '2']), ['ACL', 'DELUSER', '1', '2'] ); }); diff --git a/packages/client/lib/commands/ACL_DELUSER.ts b/packages/client/lib/commands/ACL_DELUSER.ts index c0f8e15d67..5aa66becf7 100644 --- a/packages/client/lib/commands/ACL_DELUSER.ts +++ b/packages/client/lib/commands/ACL_DELUSER.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(username: RedisVariadicArgument) { - return pushVariadicArguments(['ACL', 'DELUSER'], username); + parseCommand(parser: CommandParser, username: RedisVariadicArgument) { + parser.push('ACL', 'DELUSER'); + parser.pushVariadic(username); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_DRYRUN.spec.ts b/packages/client/lib/commands/ACL_DRYRUN.spec.ts index 519092e011..38a4def836 100644 --- a/packages/client/lib/commands/ACL_DRYRUN.spec.ts +++ b/packages/client/lib/commands/ACL_DRYRUN.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_DRYRUN from './ACL_DRYRUN'; +import { parseArgs } from './generic-transformers'; describe('ACL DRYRUN', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - ACL_DRYRUN.transformArguments('default', ['GET', 'key']), + parseArgs(ACL_DRYRUN, 'default', ['GET', 'key']), ['ACL', 'DRYRUN', 'default', 'GET', 'key'] ); }); diff --git a/packages/client/lib/commands/ACL_DRYRUN.ts b/packages/client/lib/commands/ACL_DRYRUN.ts index 257f0fe61e..09a51bc36f 100644 --- a/packages/client/lib/commands/ACL_DRYRUN.ts +++ b/packages/client/lib/commands/ACL_DRYRUN.ts @@ -1,15 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(username: RedisArgument, command: Array) { - return [ - 'ACL', - 'DRYRUN', - username, - ...command - ]; + parseCommand(parser: CommandParser, username: RedisArgument, command: Array) { + parser.push('ACL', 'DRYRUN', username, ...command); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> | BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_GENPASS.spec.ts b/packages/client/lib/commands/ACL_GENPASS.spec.ts index 44c1e167eb..35e161f424 100644 --- a/packages/client/lib/commands/ACL_GENPASS.spec.ts +++ b/packages/client/lib/commands/ACL_GENPASS.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_GENPASS from './ACL_GENPASS'; +import { parseArgs } from './generic-transformers'; describe('ACL GENPASS', () => { testUtils.isVersionGreaterThanHook([6]); @@ -8,14 +9,14 @@ describe('ACL GENPASS', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ACL_GENPASS.transformArguments(), + parseArgs(ACL_GENPASS), ['ACL', 'GENPASS'] ); }); it('with bits', () => { assert.deepEqual( - ACL_GENPASS.transformArguments(128), + parseArgs(ACL_GENPASS, 128), ['ACL', 'GENPASS', '128'] ); }); diff --git a/packages/client/lib/commands/ACL_GENPASS.ts b/packages/client/lib/commands/ACL_GENPASS.ts index be89ff90a9..b5caa29b9b 100644 --- a/packages/client/lib/commands/ACL_GENPASS.ts +++ b/packages/client/lib/commands/ACL_GENPASS.ts @@ -1,16 +1,14 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(bits?: number) { - const args = ['ACL', 'GENPASS']; - + parseCommand(parser: CommandParser, bits?: number) { + parser.push('ACL', 'GENPASS'); if (bits) { - args.push(bits.toString()); + parser.push(bits.toString()); } - - return args; }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_GETUSER.spec.ts b/packages/client/lib/commands/ACL_GETUSER.spec.ts index 4735157112..83776a3473 100644 --- a/packages/client/lib/commands/ACL_GETUSER.spec.ts +++ b/packages/client/lib/commands/ACL_GETUSER.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_GETUSER from './ACL_GETUSER'; +import { parseArgs } from './generic-transformers'; describe('ACL GETUSER', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_GETUSER.transformArguments('username'), + parseArgs(ACL_GETUSER, 'username'), ['ACL', 'GETUSER', 'username'] ); }); diff --git a/packages/client/lib/commands/ACL_GETUSER.ts b/packages/client/lib/commands/ACL_GETUSER.ts index cbbf48a4c6..b4764ad744 100644 --- a/packages/client/lib/commands/ACL_GETUSER.ts +++ b/packages/client/lib/commands/ACL_GETUSER.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; type AclUser = TuplesToMapReply<[ @@ -17,10 +18,10 @@ type AclUser = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(username: RedisArgument) { - return ['ACL', 'GETUSER', username]; + parseCommand(parser: CommandParser, username: RedisArgument) { + parser.push('ACL', 'GETUSER', username); }, transformReply: { 2: (reply: UnwrapReply>) => ({ diff --git a/packages/client/lib/commands/ACL_LIST.spec.ts b/packages/client/lib/commands/ACL_LIST.spec.ts index b188cae30b..0f67aaa53e 100644 --- a/packages/client/lib/commands/ACL_LIST.spec.ts +++ b/packages/client/lib/commands/ACL_LIST.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_LIST from './ACL_LIST'; +import { parseArgs } from './generic-transformers'; describe('ACL LIST', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_LIST.transformArguments(), + parseArgs(ACL_LIST), ['ACL', 'LIST'] ); }); diff --git a/packages/client/lib/commands/ACL_LIST.ts b/packages/client/lib/commands/ACL_LIST.ts index 1a831a4987..b5f82cf272 100644 --- a/packages/client/lib/commands/ACL_LIST.ts +++ b/packages/client/lib/commands/ACL_LIST.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ACL', 'LIST']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'LIST'); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_LOAD.spec.ts b/packages/client/lib/commands/ACL_LOAD.spec.ts index 68552164ce..a41ce45e8a 100644 --- a/packages/client/lib/commands/ACL_LOAD.spec.ts +++ b/packages/client/lib/commands/ACL_LOAD.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import ACL_LOAD from './ACL_LOAD'; +import { parseArgs } from './generic-transformers'; describe('ACL LOAD', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_LOAD.transformArguments(), + parseArgs(ACL_LOAD), ['ACL', 'LOAD'] ); }); diff --git a/packages/client/lib/commands/ACL_LOAD.ts b/packages/client/lib/commands/ACL_LOAD.ts index 39587829b1..dc4320b99f 100644 --- a/packages/client/lib/commands/ACL_LOAD.ts +++ b/packages/client/lib/commands/ACL_LOAD.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ACL', 'LOAD']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'LOAD'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_LOG.spec.ts b/packages/client/lib/commands/ACL_LOG.spec.ts index b85a7076f4..7da61faca3 100644 --- a/packages/client/lib/commands/ACL_LOG.spec.ts +++ b/packages/client/lib/commands/ACL_LOG.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_LOG from './ACL_LOG'; +import { parseArgs } from './generic-transformers'; describe('ACL LOG', () => { testUtils.isVersionGreaterThanHook([6]); @@ -8,14 +9,14 @@ describe('ACL LOG', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ACL_LOG.transformArguments(), + parseArgs(ACL_LOG), ['ACL', 'LOG'] ); }); it('with count', () => { assert.deepEqual( - ACL_LOG.transformArguments(10), + parseArgs(ACL_LOG, 10), ['ACL', 'LOG', '10'] ); }); diff --git a/packages/client/lib/commands/ACL_LOG.ts b/packages/client/lib/commands/ACL_LOG.ts index 0f0a976e09..4cf2722ec8 100644 --- a/packages/client/lib/commands/ACL_LOG.ts +++ b/packages/client/lib/commands/ACL_LOG.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command, TypeMapping } from '../RESP/types'; import { transformDoubleReply } from './generic-transformers'; @@ -18,16 +19,13 @@ export type AclLogReply = ArrayReply>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(count?: number) { - const args = ['ACL', 'LOG']; - - if (count !== undefined) { - args.push(count.toString()); + parseCommand(parser: CommandParser, count?: number) { + parser.push('ACL', 'LOG'); + if (count != undefined) { + parser.push(count.toString()); } - - return args; }, transformReply: { 2: (reply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/commands/ACL_LOG_RESET.spec.ts b/packages/client/lib/commands/ACL_LOG_RESET.spec.ts index 8849440c1a..62d193a132 100644 --- a/packages/client/lib/commands/ACL_LOG_RESET.spec.ts +++ b/packages/client/lib/commands/ACL_LOG_RESET.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ACL_LOG_RESET from './ACL_LOG_RESET'; +import { parseArgs } from './generic-transformers'; describe('ACL LOG RESET', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_LOG_RESET.transformArguments(), + parseArgs(ACL_LOG_RESET), ['ACL', 'LOG', 'RESET'] ); }); diff --git a/packages/client/lib/commands/ACL_LOG_RESET.ts b/packages/client/lib/commands/ACL_LOG_RESET.ts index 91d58d538e..9a692129bd 100644 --- a/packages/client/lib/commands/ACL_LOG_RESET.ts +++ b/packages/client/lib/commands/ACL_LOG_RESET.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; import ACL_LOG from './ACL_LOG'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: ACL_LOG.IS_READ_ONLY, - transformArguments() { - return ['ACL', 'LOG', 'RESET']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'LOG', 'RESET'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_SAVE.spec.ts b/packages/client/lib/commands/ACL_SAVE.spec.ts index 1fe402867e..98f7c9f183 100644 --- a/packages/client/lib/commands/ACL_SAVE.spec.ts +++ b/packages/client/lib/commands/ACL_SAVE.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import ACL_SAVE from './ACL_SAVE'; +import { parseArgs } from './generic-transformers'; describe('ACL SAVE', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_SAVE.transformArguments(), + parseArgs(ACL_SAVE), ['ACL', 'SAVE'] ); }); diff --git a/packages/client/lib/commands/ACL_SAVE.ts b/packages/client/lib/commands/ACL_SAVE.ts index 8c2e2dab11..ec24522724 100644 --- a/packages/client/lib/commands/ACL_SAVE.ts +++ b/packages/client/lib/commands/ACL_SAVE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ACL', 'SAVE']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'SAVE'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_SETUSER.spec.ts b/packages/client/lib/commands/ACL_SETUSER.spec.ts index 10aea62ed0..9f39868e80 100644 --- a/packages/client/lib/commands/ACL_SETUSER.spec.ts +++ b/packages/client/lib/commands/ACL_SETUSER.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import ACL_SETUSER from './ACL_SETUSER'; +import { parseArgs } from './generic-transformers'; describe('ACL SETUSER', () => { testUtils.isVersionGreaterThanHook([6]); @@ -8,14 +9,14 @@ describe('ACL SETUSER', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ACL_SETUSER.transformArguments('username', 'allkeys'), + parseArgs(ACL_SETUSER, 'username', 'allkeys'), ['ACL', 'SETUSER', 'username', 'allkeys'] ); }); it('array', () => { assert.deepEqual( - ACL_SETUSER.transformArguments('username', ['allkeys', 'allchannels']), + parseArgs(ACL_SETUSER, 'username', ['allkeys', 'allchannels']), ['ACL', 'SETUSER', 'username', 'allkeys', 'allchannels'] ); }); diff --git a/packages/client/lib/commands/ACL_SETUSER.ts b/packages/client/lib/commands/ACL_SETUSER.ts index c99fec3d9b..cad013f4d1 100644 --- a/packages/client/lib/commands/ACL_SETUSER.ts +++ b/packages/client/lib/commands/ACL_SETUSER.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(username: RedisArgument, rule: RedisVariadicArgument) { - return pushVariadicArguments(['ACL', 'SETUSER', username], rule); + parseCommand(parser: CommandParser, username: RedisArgument, rule: RedisVariadicArgument) { + parser.push('ACL', 'SETUSER', username); + parser.pushVariadic(rule); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_USERS.spec.ts b/packages/client/lib/commands/ACL_USERS.spec.ts index 2d433d4ec1..d897b61e4f 100644 --- a/packages/client/lib/commands/ACL_USERS.spec.ts +++ b/packages/client/lib/commands/ACL_USERS.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import ACL_USERS from './ACL_USERS'; +import { parseArgs } from './generic-transformers'; describe('ACL USERS', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_USERS.transformArguments(), + parseArgs(ACL_USERS), ['ACL', 'USERS'] ); }); diff --git a/packages/client/lib/commands/ACL_USERS.ts b/packages/client/lib/commands/ACL_USERS.ts index ee8c619f25..6ce4c6d84e 100644 --- a/packages/client/lib/commands/ACL_USERS.ts +++ b/packages/client/lib/commands/ACL_USERS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ACL', 'USERS']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'USERS'); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ACL_WHOAMI.spec.ts b/packages/client/lib/commands/ACL_WHOAMI.spec.ts index 24a5cbd1d6..f939c657a7 100644 --- a/packages/client/lib/commands/ACL_WHOAMI.spec.ts +++ b/packages/client/lib/commands/ACL_WHOAMI.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import ACL_WHOAMI from './ACL_WHOAMI'; +import { parseArgs } from './generic-transformers'; describe('ACL WHOAMI', () => { testUtils.isVersionGreaterThanHook([6]); it('transformArguments', () => { assert.deepEqual( - ACL_WHOAMI.transformArguments(), + parseArgs(ACL_WHOAMI), ['ACL', 'WHOAMI'] ); }); diff --git a/packages/client/lib/commands/ACL_WHOAMI.ts b/packages/client/lib/commands/ACL_WHOAMI.ts index 81a1c84a3c..eb21a75af5 100644 --- a/packages/client/lib/commands/ACL_WHOAMI.ts +++ b/packages/client/lib/commands/ACL_WHOAMI.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ACL', 'WHOAMI']; + parseCommand(parser: CommandParser) { + parser.push('ACL', 'WHOAMI'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/APPEND.spec.ts b/packages/client/lib/commands/APPEND.spec.ts index ca18a00ac4..925c16917b 100644 --- a/packages/client/lib/commands/APPEND.spec.ts +++ b/packages/client/lib/commands/APPEND.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import APPEND from './APPEND'; +import { parseArgs } from './generic-transformers'; describe('APPEND', () => { it('transformArguments', () => { assert.deepEqual( - APPEND.transformArguments('key', 'value'), + parseArgs(APPEND, 'key', 'value'), ['APPEND', 'key', 'value'] ); }); diff --git a/packages/client/lib/commands/APPEND.ts b/packages/client/lib/commands/APPEND.ts index 1bc0102499..18fc5c7b3a 100644 --- a/packages/client/lib/commands/APPEND.ts +++ b/packages/client/lib/commands/APPEND.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, value: RedisArgument) { - return ['APPEND', key, value]; + parseCommand(parser: CommandParser, key: RedisArgument, value: RedisArgument) { + parser.push('APPEND', key, value); }, + transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ASKING.spec.ts b/packages/client/lib/commands/ASKING.spec.ts index bd83bec599..7be4d25d44 100644 --- a/packages/client/lib/commands/ASKING.spec.ts +++ b/packages/client/lib/commands/ASKING.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import ASKING from './ASKING'; +import { parseArgs } from './generic-transformers'; describe('ASKING', () => { it('transformArguments', () => { assert.deepEqual( - ASKING.transformArguments(), + parseArgs(ASKING), ['ASKING'] ); }); diff --git a/packages/client/lib/commands/ASKING.ts b/packages/client/lib/commands/ASKING.ts index c6ada477ee..92ce8f7239 100644 --- a/packages/client/lib/commands/ASKING.ts +++ b/packages/client/lib/commands/ASKING.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; +export const ASKING_CMD = 'ASKING'; + export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ASKING']; + parseCommand(parser: CommandParser) { + parser.push(ASKING_CMD); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/AUTH.spec.ts b/packages/client/lib/commands/AUTH.spec.ts index 2da016ba87..762dd24f16 100644 --- a/packages/client/lib/commands/AUTH.spec.ts +++ b/packages/client/lib/commands/AUTH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import AUTH from './AUTH'; +import { parseArgs } from './generic-transformers'; describe('AUTH', () => { describe('transformArguments', () => { it('password only', () => { assert.deepEqual( - AUTH.transformArguments({ + parseArgs(AUTH, { password: 'password' }), ['AUTH', 'password'] @@ -14,7 +15,7 @@ describe('AUTH', () => { it('username & password', () => { assert.deepEqual( - AUTH.transformArguments({ + parseArgs(AUTH, { username: 'username', password: 'password' }), diff --git a/packages/client/lib/commands/AUTH.ts b/packages/client/lib/commands/AUTH.ts index 4c7a0b0c76..85b48b0026 100644 --- a/packages/client/lib/commands/AUTH.ts +++ b/packages/client/lib/commands/AUTH.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export interface AuthOptions { @@ -6,18 +7,14 @@ export interface AuthOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments({ username, password }: AuthOptions) { - const args: Array = ['AUTH']; - + parseCommand(parser: CommandParser, { username, password }: AuthOptions) { + parser.push('AUTH'); if (username !== undefined) { - args.push(username); + parser.push(username); } - - args.push(password); - - return args; + parser.push(password); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/BGREWRITEAOF.spec.ts b/packages/client/lib/commands/BGREWRITEAOF.spec.ts index 5447fc70a7..f58ec9a576 100644 --- a/packages/client/lib/commands/BGREWRITEAOF.spec.ts +++ b/packages/client/lib/commands/BGREWRITEAOF.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BGREWRITEAOF from './BGREWRITEAOF'; +import { parseArgs } from './generic-transformers'; describe('BGREWRITEAOF', () => { it('transformArguments', () => { assert.deepEqual( - BGREWRITEAOF.transformArguments(), + parseArgs(BGREWRITEAOF), ['BGREWRITEAOF'] ); }); diff --git a/packages/client/lib/commands/BGREWRITEAOF.ts b/packages/client/lib/commands/BGREWRITEAOF.ts index 5f9a46e318..c658f3e852 100644 --- a/packages/client/lib/commands/BGREWRITEAOF.ts +++ b/packages/client/lib/commands/BGREWRITEAOF.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['BGREWRITEAOF']; + parseCommand(parser: CommandParser) { + parser.push('BGREWRITEAOF'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BGSAVE.spec.ts b/packages/client/lib/commands/BGSAVE.spec.ts index 7944722dd5..dcf7b81511 100644 --- a/packages/client/lib/commands/BGSAVE.spec.ts +++ b/packages/client/lib/commands/BGSAVE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BGSAVE from './BGSAVE'; +import { parseArgs } from './generic-transformers'; describe('BGSAVE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - BGSAVE.transformArguments(), + parseArgs(BGSAVE), ['BGSAVE'] ); }); it('with SCHEDULE', () => { assert.deepEqual( - BGSAVE.transformArguments({ + parseArgs(BGSAVE, { SCHEDULE: true }), ['BGSAVE', 'SCHEDULE'] diff --git a/packages/client/lib/commands/BGSAVE.ts b/packages/client/lib/commands/BGSAVE.ts index dc0f505670..1fd6c6b5bd 100644 --- a/packages/client/lib/commands/BGSAVE.ts +++ b/packages/client/lib/commands/BGSAVE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export interface BgSaveOptions { @@ -5,16 +6,13 @@ export interface BgSaveOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(options?: BgSaveOptions) { - const args = ['BGSAVE']; - + parseCommand(parser: CommandParser, options?: BgSaveOptions) { + parser.push('BGSAVE'); if (options?.SCHEDULE) { - args.push('SCHEDULE'); + parser.push('SCHEDULE'); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BITCOUNT.spec.ts b/packages/client/lib/commands/BITCOUNT.spec.ts index ceb6476a31..e299047294 100644 --- a/packages/client/lib/commands/BITCOUNT.spec.ts +++ b/packages/client/lib/commands/BITCOUNT.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BITCOUNT from './BITCOUNT'; +import { parseArgs } from './generic-transformers'; describe('BITCOUNT', () => { - describe('transformArguments', () => { + describe('parseCommand', () => { it('simple', () => { assert.deepEqual( - BITCOUNT.transformArguments('key'), + parseArgs(BITCOUNT, 'key'), ['BITCOUNT', 'key'] ); }); @@ -14,7 +15,7 @@ describe('BITCOUNT', () => { describe('with range', () => { it('simple', () => { assert.deepEqual( - BITCOUNT.transformArguments('key', { + parseArgs(BITCOUNT, 'key', { start: 0, end: 1 }), @@ -24,7 +25,7 @@ describe('BITCOUNT', () => { it('with mode', () => { assert.deepEqual( - BITCOUNT.transformArguments('key', { + parseArgs(BITCOUNT, 'key', { start: 0, end: 1, mode: 'BIT' diff --git a/packages/client/lib/commands/BITCOUNT.ts b/packages/client/lib/commands/BITCOUNT.ts index 6ec6b89be8..decfb754db 100644 --- a/packages/client/lib/commands/BITCOUNT.ts +++ b/packages/client/lib/commands/BITCOUNT.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export interface BitCountRange { @@ -7,23 +8,19 @@ export interface BitCountRange { } export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, range?: BitCountRange) { - const args = ['BITCOUNT', key]; - + parseCommand(parser: CommandParser, key: RedisArgument, range?: BitCountRange) { + parser.push('BITCOUNT'); + parser.pushKey(key); if (range) { - args.push( - range.start.toString(), - range.end.toString() - ); + parser.push(range.start.toString()); + parser.push(range.end.toString()); if (range.mode) { - args.push(range.mode); + parser.push(range.mode); } } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BITFIELD.spec.ts b/packages/client/lib/commands/BITFIELD.spec.ts index 7f80575549..5fcc112466 100644 --- a/packages/client/lib/commands/BITFIELD.spec.ts +++ b/packages/client/lib/commands/BITFIELD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BITFIELD from './BITFIELD'; +import { parseArgs } from './generic-transformers'; describe('BITFIELD', () => { it('transformArguments', () => { assert.deepEqual( - BITFIELD.transformArguments('key', [{ + parseArgs(BITFIELD, 'key', [{ operation: 'OVERFLOW', behavior: 'WRAP' }, { diff --git a/packages/client/lib/commands/BITFIELD.ts b/packages/client/lib/commands/BITFIELD.ts index 5d7d4bf728..f095b4cf7a 100644 --- a/packages/client/lib/commands/BITFIELD.ts +++ b/packages/client/lib/commands/BITFIELD.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '../RESP/types'; export type BitFieldEncoding = `${'i' | 'u'}${number}`; @@ -39,15 +40,15 @@ export type BitFieldRoOperations = Array< >; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, operations: BitFieldOperations) { - const args = ['BITFIELD', key]; + parseCommand(parser: CommandParser, key: RedisArgument, operations: BitFieldOperations) { + parser.push('BITFIELD'); + parser.pushKey(key); for (const options of operations) { switch (options.operation) { case 'GET': - args.push( + parser.push( 'GET', options.encoding, options.offset.toString() @@ -55,7 +56,7 @@ export default { break; case 'SET': - args.push( + parser.push( 'SET', options.encoding, options.offset.toString(), @@ -64,7 +65,7 @@ export default { break; case 'INCRBY': - args.push( + parser.push( 'INCRBY', options.encoding, options.offset.toString(), @@ -73,15 +74,13 @@ export default { break; case 'OVERFLOW': - args.push( + parser.push( 'OVERFLOW', options.behavior ); break; } } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BITFIELD_RO.spec.ts b/packages/client/lib/commands/BITFIELD_RO.spec.ts index 0793100193..f2c1797412 100644 --- a/packages/client/lib/commands/BITFIELD_RO.spec.ts +++ b/packages/client/lib/commands/BITFIELD_RO.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BITFIELD_RO from './BITFIELD_RO'; +import { parseArgs } from './generic-transformers'; describe('BITFIELD_RO', () => { testUtils.isVersionGreaterThanHook([6, 2]); - it('transformArguments', () => { + it('parseCommand', () => { assert.deepEqual( - BITFIELD_RO.transformArguments('key', [{ + parseArgs(BITFIELD_RO, 'key', [{ encoding: 'i8', offset: 0 }]), diff --git a/packages/client/lib/commands/BITFIELD_RO.ts b/packages/client/lib/commands/BITFIELD_RO.ts index 99e500abc0..66001718b8 100644 --- a/packages/client/lib/commands/BITFIELD_RO.ts +++ b/packages/client/lib/commands/BITFIELD_RO.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NumberReply, Command } from '../RESP/types'; import { BitFieldGetOperation } from './BITFIELD'; @@ -6,20 +7,17 @@ export type BitFieldRoOperations = Array< >; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, operations: BitFieldRoOperations) { - const args = ['BITFIELD_RO', key]; + parseCommand(parser: CommandParser, key: RedisArgument, operations: BitFieldRoOperations) { + parser.push('BITFIELD_RO'); + parser.pushKey(key); for (const operation of operations) { - args.push( - 'GET', - operation.encoding, - operation.offset.toString() - ); + parser.push('GET'); + parser.push(operation.encoding); + parser.push(operation.offset.toString()) } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BITOP.spec.ts b/packages/client/lib/commands/BITOP.spec.ts index 4df1782467..25fe48fc13 100644 --- a/packages/client/lib/commands/BITOP.spec.ts +++ b/packages/client/lib/commands/BITOP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BITOP from './BITOP'; +import { parseArgs } from './generic-transformers'; describe('BITOP', () => { describe('transformArguments', () => { it('single key', () => { assert.deepEqual( - BITOP.transformArguments('AND', 'destKey', 'key'), + parseArgs(BITOP, 'AND', 'destKey', 'key'), ['BITOP', 'AND', 'destKey', 'key'] ); }); it('multiple keys', () => { assert.deepEqual( - BITOP.transformArguments('AND', 'destKey', ['1', '2']), + parseArgs(BITOP, 'AND', 'destKey', ['1', '2']), ['BITOP', 'AND', 'destKey', '1', '2'] ); }); diff --git a/packages/client/lib/commands/BITOP.ts b/packages/client/lib/commands/BITOP.ts index 4c34845699..bb77014811 100644 --- a/packages/client/lib/commands/BITOP.ts +++ b/packages/client/lib/commands/BITOP.ts @@ -1,17 +1,20 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export type BitOperations = 'AND' | 'OR' | 'XOR' | 'NOT'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, operation: BitOperations, destKey: RedisArgument, key: RedisVariadicArgument ) { - return pushVariadicArguments(['BITOP', operation, destKey], key); + parser.push('BITOP', operation); + parser.pushKey(destKey); + parser.pushKeys(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BITPOS.spec.ts b/packages/client/lib/commands/BITPOS.spec.ts index 6194056005..c699deab83 100644 --- a/packages/client/lib/commands/BITPOS.spec.ts +++ b/packages/client/lib/commands/BITPOS.spec.ts @@ -1,33 +1,34 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import BITPOS from './BITPOS'; +import { parseArgs } from './generic-transformers'; describe('BITPOS', () => { - describe('transformArguments', () => { + describe('parseCommand', () => { it('simple', () => { assert.deepEqual( - BITPOS.transformArguments('key', 1), + parseArgs(BITPOS, 'key', 1), ['BITPOS', 'key', '1'] ); }); it('with start', () => { assert.deepEqual( - BITPOS.transformArguments('key', 1, 1), + parseArgs(BITPOS, 'key', 1, 1), ['BITPOS', 'key', '1', '1'] ); }); it('with start and end', () => { assert.deepEqual( - BITPOS.transformArguments('key', 1, 1, -1), + parseArgs(BITPOS, 'key', 1, 1, -1), ['BITPOS', 'key', '1', '1', '-1'] ); }); it('with start, end and mode', () => { assert.deepEqual( - BITPOS.transformArguments('key', 1, 1, -1, 'BIT'), + parseArgs(BITPOS, 'key', 1, 1, -1, 'BIT'), ['BITPOS', 'key', '1', '1', '-1', 'BIT'] ); }); diff --git a/packages/client/lib/commands/BITPOS.ts b/packages/client/lib/commands/BITPOS.ts index 5d6276dffc..57e3a63b68 100644 --- a/packages/client/lib/commands/BITPOS.ts +++ b/packages/client/lib/commands/BITPOS.ts @@ -1,31 +1,32 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { BitValue } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand(parser: CommandParser, key: RedisArgument, bit: BitValue, start?: number, end?: number, mode?: 'BYTE' | 'BIT' ) { - const args = ['BITPOS', key, bit.toString()]; + parser.push('BITPOS'); + parser.pushKey(key); + parser.push(bit.toString()); if (start !== undefined) { - args.push(start.toString()); + parser.push(start.toString()); } if (end !== undefined) { - args.push(end.toString()); + parser.push(end.toString()); } if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BLMOVE.spec.ts b/packages/client/lib/commands/BLMOVE.spec.ts index 0eca8c6100..d4e9e024a8 100644 --- a/packages/client/lib/commands/BLMOVE.spec.ts +++ b/packages/client/lib/commands/BLMOVE.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BLMOVE from './BLMOVE'; +import { parseArgs } from './generic-transformers'; describe('BLMOVE', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - BLMOVE.transformArguments('source', 'destination', 'LEFT', 'RIGHT', 0), + parseArgs(BLMOVE, 'source', 'destination', 'LEFT', 'RIGHT', 0), ['BLMOVE', 'source', 'destination', 'LEFT', 'RIGHT', '0'] ); }); diff --git a/packages/client/lib/commands/BLMOVE.ts b/packages/client/lib/commands/BLMOVE.ts index c7e4844375..b0ada7cdb2 100644 --- a/packages/client/lib/commands/BLMOVE.ts +++ b/packages/client/lib/commands/BLMOVE.ts @@ -1,24 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; import { ListSide } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, source: RedisArgument, destination: RedisArgument, sourceSide: ListSide, destinationSide: ListSide, timeout: number ) { - return [ - 'BLMOVE', - source, - destination, - sourceSide, - destinationSide, - timeout.toString() - ]; + parser.push('BLMOVE'); + parser.pushKeys([source, destination]); + parser.push(sourceSide, destinationSide, timeout.toString()) }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BLMPOP.spec.ts b/packages/client/lib/commands/BLMPOP.spec.ts index b40556b1e4..6cda524b50 100644 --- a/packages/client/lib/commands/BLMPOP.spec.ts +++ b/packages/client/lib/commands/BLMPOP.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BLMPOP from './BLMPOP'; +import { parseArgs } from './generic-transformers'; describe('BLMPOP', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('BLMPOP', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - BLMPOP.transformArguments(0, 'key', 'LEFT'), + parseArgs(BLMPOP, 0, 'key', 'LEFT'), ['BLMPOP', '0', '1', 'key', 'LEFT'] ); }); it('with COUNT', () => { assert.deepEqual( - BLMPOP.transformArguments(0, 'key', 'LEFT', { + parseArgs(BLMPOP, 0, 'key', 'LEFT', { COUNT: 1 }), ['BLMPOP', '0', '1', 'key', 'LEFT', 'COUNT', '1'] diff --git a/packages/client/lib/commands/BLMPOP.ts b/packages/client/lib/commands/BLMPOP.ts index 3122e90860..15d03f8d82 100644 --- a/packages/client/lib/commands/BLMPOP.ts +++ b/packages/client/lib/commands/BLMPOP.ts @@ -1,17 +1,12 @@ +import { CommandParser } from '../client/parser'; import { Command } from '../RESP/types'; -import LMPOP, { LMPopArguments, transformLMPopArguments } from './LMPOP'; +import LMPOP, { LMPopArguments, parseLMPopArguments } from './LMPOP'; export default { - FIRST_KEY_INDEX: 3, IS_READ_ONLY: false, - transformArguments( - timeout: number, - ...args: LMPopArguments - ) { - return transformLMPopArguments( - ['BLMPOP', timeout.toString()], - ...args - ); - }, + parseCommand(parser: CommandParser, timeout: number, ...args: LMPopArguments) { + parser.push('BLMPOP', timeout.toString()); + parseLMPopArguments(parser, ...args); + }, transformReply: LMPOP.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BLPOP.spec.ts b/packages/client/lib/commands/BLPOP.spec.ts index 4bcc08d0fc..1bb53a774b 100644 --- a/packages/client/lib/commands/BLPOP.spec.ts +++ b/packages/client/lib/commands/BLPOP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BLPOP from './BLPOP'; +import { parseArgs } from './generic-transformers'; describe('BLPOP', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - BLPOP.transformArguments('key', 0), + parseArgs(BLPOP, 'key', 0), ['BLPOP', 'key', '0'] ); }); it('multiple', () => { assert.deepEqual( - BLPOP.transformArguments(['1', '2'], 0), + parseArgs(BLPOP, ['1', '2'], 0), ['BLPOP', '1', '2', '0'] ); }); diff --git a/packages/client/lib/commands/BLPOP.ts b/packages/client/lib/commands/BLPOP.ts index c9f8b4775e..aa0b30e768 100644 --- a/packages/client/lib/commands/BLPOP.ts +++ b/packages/client/lib/commands/BLPOP.ts @@ -1,16 +1,13 @@ +import { CommandParser } from '../client/parser'; import { UnwrapReply, NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( - key: RedisVariadicArgument, - timeout: number - ) { - const args = pushVariadicArguments(['BLPOP'], key); - args.push(timeout.toString()); - return args; + parseCommand(parser: CommandParser, key: RedisVariadicArgument, timeout: number) { + parser.push('BLPOP'); + parser.pushKeys(key); + parser.push(timeout.toString()); }, transformReply(reply: UnwrapReply>) { if (reply === null) return null; diff --git a/packages/client/lib/commands/BRPOP.spec.ts b/packages/client/lib/commands/BRPOP.spec.ts index 21631d763f..de23bb34a9 100644 --- a/packages/client/lib/commands/BRPOP.spec.ts +++ b/packages/client/lib/commands/BRPOP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BRPOP from './BRPOP'; +import { parseArgs } from './generic-transformers'; describe('BRPOP', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - BRPOP.transformArguments('key', 0), + parseArgs(BRPOP, 'key', 0), ['BRPOP', 'key', '0'] ); }); it('multiple', () => { assert.deepEqual( - BRPOP.transformArguments(['1', '2'], 0), + parseArgs(BRPOP, ['1', '2'], 0), ['BRPOP', '1', '2', '0'] ); }); diff --git a/packages/client/lib/commands/BRPOP.ts b/packages/client/lib/commands/BRPOP.ts index f9c8aaa503..401a951556 100644 --- a/packages/client/lib/commands/BRPOP.ts +++ b/packages/client/lib/commands/BRPOP.ts @@ -1,17 +1,14 @@ +import { CommandParser } from '../client/parser'; import { Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; import BLPOP from './BLPOP'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( - key: RedisVariadicArgument, - timeout: number - ) { - const args = pushVariadicArguments(['BRPOP'], key); - args.push(timeout.toString()); - return args; + parseCommand(parser: CommandParser, key: RedisVariadicArgument, timeout: number) { + parser.push('BRPOP'); + parser.pushKeys(key); + parser.push(timeout.toString()); }, transformReply: BLPOP.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BRPOPLPUSH.spec.ts b/packages/client/lib/commands/BRPOPLPUSH.spec.ts index 1f6dc48bfe..6c2a2a2c90 100644 --- a/packages/client/lib/commands/BRPOPLPUSH.spec.ts +++ b/packages/client/lib/commands/BRPOPLPUSH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BRPOPLPUSH from './BRPOPLPUSH'; +import { parseArgs } from './generic-transformers'; describe('BRPOPLPUSH', () => { it('transformArguments', () => { assert.deepEqual( - BRPOPLPUSH.transformArguments('source', 'destination', 0), + parseArgs(BRPOPLPUSH, 'source', 'destination', 0), ['BRPOPLPUSH', 'source', 'destination', '0'] ); }); diff --git a/packages/client/lib/commands/BRPOPLPUSH.ts b/packages/client/lib/commands/BRPOPLPUSH.ts index d342ea7572..72f63a1c1e 100644 --- a/packages/client/lib/commands/BRPOPLPUSH.ts +++ b/packages/client/lib/commands/BRPOPLPUSH.ts @@ -1,14 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - source: RedisArgument, - destination: RedisArgument, - timeout: number - ) { - return ['BRPOPLPUSH', source, destination, timeout.toString()]; + parseCommand(parser: CommandParser, source: RedisArgument, destination: RedisArgument, timeout: number) { + parser.push('BRPOPLPUSH'); + parser.pushKeys([source, destination]); + parser.push(timeout.toString()); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BZMPOP.spec.ts b/packages/client/lib/commands/BZMPOP.spec.ts index 554e6898d6..8b082a214e 100644 --- a/packages/client/lib/commands/BZMPOP.spec.ts +++ b/packages/client/lib/commands/BZMPOP.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BZMPOP from './BZMPOP'; +import { parseArgs } from './generic-transformers'; describe('BZMPOP', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('BZMPOP', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - BZMPOP.transformArguments(0, 'key', 'MIN'), + parseArgs(BZMPOP, 0, 'key', 'MIN'), ['BZMPOP', '0', '1', 'key', 'MIN'] ); }); it('with COUNT', () => { assert.deepEqual( - BZMPOP.transformArguments(0, 'key', 'MIN', { + parseArgs(BZMPOP, 0, 'key', 'MIN', { COUNT: 2 }), ['BZMPOP', '0', '1', 'key', 'MIN', 'COUNT', '2'] diff --git a/packages/client/lib/commands/BZMPOP.ts b/packages/client/lib/commands/BZMPOP.ts index 030aa20c66..98079b7a20 100644 --- a/packages/client/lib/commands/BZMPOP.ts +++ b/packages/client/lib/commands/BZMPOP.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { Command } from '../RESP/types'; -import ZMPOP, { ZMPopArguments, transformZMPopArguments } from './ZMPOP'; +import ZMPOP, { parseZMPopArguments, ZMPopArguments } from './ZMPOP'; export default { - FIRST_KEY_INDEX: 3, IS_READ_ONLY: false, - transformArguments(timeout: number, ...args: ZMPopArguments) { - return transformZMPopArguments(['BZMPOP', timeout.toString()], ...args); + parseCommand(parser: CommandParser, timeout: number, ...args: ZMPopArguments) { + parser.push('BZMPOP', timeout.toString()); + parseZMPopArguments(parser, ...args); }, transformReply: ZMPOP.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/BZPOPMAX.spec.ts b/packages/client/lib/commands/BZPOPMAX.spec.ts index 1f0a4d44f0..fbf6086232 100644 --- a/packages/client/lib/commands/BZPOPMAX.spec.ts +++ b/packages/client/lib/commands/BZPOPMAX.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BZPOPMAX from './BZPOPMAX'; +import { parseArgs } from './generic-transformers'; describe('BZPOPMAX', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - BZPOPMAX.transformArguments('key', 0), + parseArgs(BZPOPMAX, 'key', 0), ['BZPOPMAX', 'key', '0'] ); }); it('multiple', () => { assert.deepEqual( - BZPOPMAX.transformArguments(['1', '2'], 0), + parseArgs(BZPOPMAX, ['1', '2'], 0), ['BZPOPMAX', '1', '2', '0'] ); }); diff --git a/packages/client/lib/commands/BZPOPMAX.ts b/packages/client/lib/commands/BZPOPMAX.ts index 792a559257..1a5159269e 100644 --- a/packages/client/lib/commands/BZPOPMAX.ts +++ b/packages/client/lib/commands/BZPOPMAX.ts @@ -1,23 +1,13 @@ -import { RedisArgument, NullReply, TuplesReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments, transformDoubleReply } from './generic-transformers'; - -export function transformBZPopArguments( - command: RedisArgument, - key: RedisVariadicArgument, - timeout: number -) { - const args = pushVariadicArguments([command], key); - args.push(timeout.toString()); - return args; -} - -export type BZPopArguments = typeof transformBZPopArguments extends (_: any, ...args: infer T) => any ? T : never; +import { CommandParser } from '../client/parser'; +import { NullReply, TuplesReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; +import { RedisVariadicArgument, transformDoubleReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(...args: BZPopArguments) { - return transformBZPopArguments('BZPOPMAX', ...args); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument, timeout: number) { + parser.push('BZPOPMAX'); + parser.pushKeys(keys); + parser.push(timeout.toString()); }, transformReply: { 2( diff --git a/packages/client/lib/commands/BZPOPMIN.spec.ts b/packages/client/lib/commands/BZPOPMIN.spec.ts index 7f39f7d189..2f8cab8ded 100644 --- a/packages/client/lib/commands/BZPOPMIN.spec.ts +++ b/packages/client/lib/commands/BZPOPMIN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils'; import BZPOPMIN from './BZPOPMIN'; +import { parseArgs } from './generic-transformers'; describe('BZPOPMIN', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - BZPOPMIN.transformArguments('key', 0), + parseArgs(BZPOPMIN, 'key', 0), ['BZPOPMIN', 'key', '0'] ); }); it('multiple', () => { assert.deepEqual( - BZPOPMIN.transformArguments(['1', '2'], 0), + parseArgs(BZPOPMIN, ['1', '2'], 0), ['BZPOPMIN', '1', '2', '0'] ); }); diff --git a/packages/client/lib/commands/BZPOPMIN.ts b/packages/client/lib/commands/BZPOPMIN.ts index f27e623528..9dc4c47e13 100644 --- a/packages/client/lib/commands/BZPOPMIN.ts +++ b/packages/client/lib/commands/BZPOPMIN.ts @@ -1,11 +1,14 @@ +import { CommandParser } from '../client/parser'; import { Command } from '../RESP/types'; -import BZPOPMAX, { BZPopArguments, transformBZPopArguments } from './BZPOPMAX'; +import { RedisVariadicArgument } from './generic-transformers'; +import BZPOPMAX from './BZPOPMAX'; export default { - FIRST_KEY_INDEX: BZPOPMAX.FIRST_KEY_INDEX, IS_READ_ONLY: BZPOPMAX.IS_READ_ONLY, - transformArguments(...args: BZPopArguments) { - return transformBZPopArguments('BZPOPMIN', ...args); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument, timeout: number) { + parser.push('BZPOPMIN'); + parser.pushKeys(keys); + parser.push(timeout.toString()); }, transformReply: BZPOPMAX.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_CACHING.spec.ts b/packages/client/lib/commands/CLIENT_CACHING.spec.ts index 34023f9892..ad3511b3e9 100644 --- a/packages/client/lib/commands/CLIENT_CACHING.spec.ts +++ b/packages/client/lib/commands/CLIENT_CACHING.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLIENT_CACHING from './CLIENT_CACHING'; +import { parseArgs } from './generic-transformers'; describe('CLIENT CACHING', () => { describe('transformArguments', () => { it('true', () => { assert.deepEqual( - CLIENT_CACHING.transformArguments(true), + parseArgs(CLIENT_CACHING, true), ['CLIENT', 'CACHING', 'YES'] ); }); it('false', () => { assert.deepEqual( - CLIENT_CACHING.transformArguments(false), + parseArgs(CLIENT_CACHING, false), ['CLIENT', 'CACHING', 'NO'] ); }); diff --git a/packages/client/lib/commands/CLIENT_CACHING.ts b/packages/client/lib/commands/CLIENT_CACHING.ts index 505ae152f8..9987e49c99 100644 --- a/packages/client/lib/commands/CLIENT_CACHING.ts +++ b/packages/client/lib/commands/CLIENT_CACHING.ts @@ -1,14 +1,15 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(value: boolean) { - return [ + parseCommand(parser: CommandParser, value: boolean) { + parser.push( 'CLIENT', 'CACHING', value ? 'YES' : 'NO' - ]; + ); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_GETNAME.spec.ts b/packages/client/lib/commands/CLIENT_GETNAME.spec.ts index 8975f1fee9..5b0dfdb843 100644 --- a/packages/client/lib/commands/CLIENT_GETNAME.spec.ts +++ b/packages/client/lib/commands/CLIENT_GETNAME.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_GETNAME from './CLIENT_GETNAME'; +import { parseArgs } from './generic-transformers'; describe('CLIENT GETNAME', () => { it('transformArguments', () => { assert.deepEqual( - CLIENT_GETNAME.transformArguments(), + parseArgs(CLIENT_GETNAME), ['CLIENT', 'GETNAME'] ); }); diff --git a/packages/client/lib/commands/CLIENT_GETNAME.ts b/packages/client/lib/commands/CLIENT_GETNAME.ts index c46b576407..2e18c43cd5 100644 --- a/packages/client/lib/commands/CLIENT_GETNAME.ts +++ b/packages/client/lib/commands/CLIENT_GETNAME.ts @@ -1,13 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return [ - 'CLIENT', - 'GETNAME' - ]; + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'GETNAME'); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_GETREDIR.spec.ts b/packages/client/lib/commands/CLIENT_GETREDIR.spec.ts index 5cfedf2a4e..a7c375fec2 100644 --- a/packages/client/lib/commands/CLIENT_GETREDIR.spec.ts +++ b/packages/client/lib/commands/CLIENT_GETREDIR.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLIENT_GETREDIR from './CLIENT_GETREDIR'; +import { parseArgs } from './generic-transformers'; describe('CLIENT GETREDIR', () => { it('transformArguments', () => { assert.deepEqual( - CLIENT_GETREDIR.transformArguments(), + parseArgs(CLIENT_GETREDIR), ['CLIENT', 'GETREDIR'] ); }); diff --git a/packages/client/lib/commands/CLIENT_GETREDIR.ts b/packages/client/lib/commands/CLIENT_GETREDIR.ts index ae0b601b4e..80cc6418da 100644 --- a/packages/client/lib/commands/CLIENT_GETREDIR.ts +++ b/packages/client/lib/commands/CLIENT_GETREDIR.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLIENT', 'GETREDIR'] + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'GETREDIR'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_ID.spec.ts b/packages/client/lib/commands/CLIENT_ID.spec.ts index 7b51e6bd93..51b308adf2 100644 --- a/packages/client/lib/commands/CLIENT_ID.spec.ts +++ b/packages/client/lib/commands/CLIENT_ID.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_ID from './CLIENT_ID'; +import { parseArgs } from './generic-transformers'; describe('CLIENT ID', () => { it('transformArguments', () => { assert.deepEqual( - CLIENT_ID.transformArguments(), + parseArgs(CLIENT_ID), ['CLIENT', 'ID'] ); }); diff --git a/packages/client/lib/commands/CLIENT_ID.ts b/packages/client/lib/commands/CLIENT_ID.ts index 165ab1931e..da58786ec3 100644 --- a/packages/client/lib/commands/CLIENT_ID.ts +++ b/packages/client/lib/commands/CLIENT_ID.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLIENT', 'ID']; + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'ID'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_INFO.spec.ts b/packages/client/lib/commands/CLIENT_INFO.spec.ts index 0aba384aa3..50345a46ce 100644 --- a/packages/client/lib/commands/CLIENT_INFO.spec.ts +++ b/packages/client/lib/commands/CLIENT_INFO.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import CLIENT_INFO from './CLIENT_INFO'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; describe('CLIENT INFO', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - CLIENT_INFO.transformArguments(), + parseArgs(CLIENT_INFO), ['CLIENT', 'INFO'] ); }); diff --git a/packages/client/lib/commands/CLIENT_INFO.ts b/packages/client/lib/commands/CLIENT_INFO.ts index 88721e2f8b..36dac17544 100644 --- a/packages/client/lib/commands/CLIENT_INFO.ts +++ b/packages/client/lib/commands/CLIENT_INFO.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { Command, VerbatimStringReply } from '../RESP/types'; export interface ClientInfoReply { @@ -56,10 +57,10 @@ export interface ClientInfoReply { const CLIENT_INFO_REGEX = /([^\s=]+)=([^\s]*)/g; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLIENT', 'INFO'] + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'INFO'); }, transformReply(rawReply: VerbatimStringReply) { const map: Record = {}; diff --git a/packages/client/lib/commands/CLIENT_KILL.spec.ts b/packages/client/lib/commands/CLIENT_KILL.spec.ts index 79254af41f..5078a26751 100644 --- a/packages/client/lib/commands/CLIENT_KILL.spec.ts +++ b/packages/client/lib/commands/CLIENT_KILL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import CLIENT_KILL, { CLIENT_KILL_FILTERS } from './CLIENT_KILL'; +import { parseArgs } from './generic-transformers'; describe('CLIENT KILL', () => { describe('transformArguments', () => { it('ADDRESS', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.ADDRESS, address: 'ip:6379' }), @@ -15,7 +16,7 @@ describe('CLIENT KILL', () => { it('LOCAL_ADDRESS', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.LOCAL_ADDRESS, localAddress: 'ip:6379' }), @@ -26,7 +27,7 @@ describe('CLIENT KILL', () => { describe('ID', () => { it('string', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.ID, id: '1' }), @@ -36,7 +37,7 @@ describe('CLIENT KILL', () => { it('number', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.ID, id: 1 }), @@ -47,7 +48,7 @@ describe('CLIENT KILL', () => { it('TYPE', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.TYPE, type: 'master' }), @@ -57,7 +58,7 @@ describe('CLIENT KILL', () => { it('USER', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.USER, username: 'username' }), @@ -67,7 +68,7 @@ describe('CLIENT KILL', () => { it('MAXAGE', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.MAXAGE, maxAge: 10 }), @@ -78,14 +79,14 @@ describe('CLIENT KILL', () => { describe('SKIP_ME', () => { it('undefined', () => { assert.deepEqual( - CLIENT_KILL.transformArguments(CLIENT_KILL_FILTERS.SKIP_ME), + parseArgs(CLIENT_KILL, CLIENT_KILL_FILTERS.SKIP_ME), ['CLIENT', 'KILL', 'SKIPME'] ); }); it('true', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.SKIP_ME, skipMe: true }), @@ -95,7 +96,7 @@ describe('CLIENT KILL', () => { it('false', () => { assert.deepEqual( - CLIENT_KILL.transformArguments({ + parseArgs(CLIENT_KILL, { filter: CLIENT_KILL_FILTERS.SKIP_ME, skipMe: false }), @@ -106,7 +107,7 @@ describe('CLIENT KILL', () => { it('TYPE & SKIP_ME', () => { assert.deepEqual( - CLIENT_KILL.transformArguments([ + parseArgs(CLIENT_KILL, [ { filter: CLIENT_KILL_FILTERS.TYPE, type: 'master' diff --git a/packages/client/lib/commands/CLIENT_KILL.ts b/packages/client/lib/commands/CLIENT_KILL.ts index c5eb5304c5..24f8f0873f 100644 --- a/packages/client/lib/commands/CLIENT_KILL.ts +++ b/packages/client/lib/commands/CLIENT_KILL.ts @@ -1,4 +1,5 @@ -import { RedisArgument, NumberReply, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { NumberReply, Command } from '../RESP/types'; export const CLIENT_KILL_FILTERS = { ADDRESS: 'ADDR', @@ -47,43 +48,42 @@ export interface ClientKillMaxAge extends ClientKillFilterCommon) { - const args = ['CLIENT', 'KILL']; + parseCommand(parser: CommandParser, filters: ClientKillFilter | Array) { + parser.push('CLIENT', 'KILL'); if (Array.isArray(filters)) { for (const filter of filters) { - pushFilter(args, filter); + pushFilter(parser, filter); } } else { - pushFilter(args, filters); + pushFilter(parser, filters); } - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; -function pushFilter(args: Array, filter: ClientKillFilter): void { +function pushFilter(parser: CommandParser, filter: ClientKillFilter): void { if (filter === CLIENT_KILL_FILTERS.SKIP_ME) { - args.push('SKIPME'); + parser.push('SKIPME'); return; } - args.push(filter.filter); + parser.push(filter.filter); switch (filter.filter) { case CLIENT_KILL_FILTERS.ADDRESS: - args.push(filter.address); + parser.push(filter.address); break; case CLIENT_KILL_FILTERS.LOCAL_ADDRESS: - args.push(filter.localAddress); + parser.push(filter.localAddress); break; case CLIENT_KILL_FILTERS.ID: - args.push( + parser.push( typeof filter.id === 'number' ? filter.id.toString() : filter.id @@ -91,19 +91,19 @@ function pushFilter(args: Array, filter: ClientKillFilter): void break; case CLIENT_KILL_FILTERS.TYPE: - args.push(filter.type); + parser.push(filter.type); break; case CLIENT_KILL_FILTERS.USER: - args.push(filter.username); + parser.push(filter.username); break; case CLIENT_KILL_FILTERS.SKIP_ME: - args.push(filter.skipMe ? 'yes' : 'no'); + parser.push(filter.skipMe ? 'yes' : 'no'); break; case CLIENT_KILL_FILTERS.MAXAGE: - args.push(filter.maxAge.toString()); + parser.push(filter.maxAge.toString()); break; } } diff --git a/packages/client/lib/commands/CLIENT_LIST.spec.ts b/packages/client/lib/commands/CLIENT_LIST.spec.ts index e967a8dc0f..34709c5f14 100644 --- a/packages/client/lib/commands/CLIENT_LIST.spec.ts +++ b/packages/client/lib/commands/CLIENT_LIST.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import CLIENT_LIST from './CLIENT_LIST'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; describe('CLIENT LIST', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLIENT_LIST.transformArguments(), + parseArgs(CLIENT_LIST), ['CLIENT', 'LIST'] ); }); it('with TYPE', () => { assert.deepEqual( - CLIENT_LIST.transformArguments({ + parseArgs(CLIENT_LIST, { TYPE: 'NORMAL' }), ['CLIENT', 'LIST', 'TYPE', 'NORMAL'] @@ -22,7 +23,7 @@ describe('CLIENT LIST', () => { it('with ID', () => { assert.deepEqual( - CLIENT_LIST.transformArguments({ + parseArgs(CLIENT_LIST, { ID: ['1', '2'] }), ['CLIENT', 'LIST', 'ID', '1', '2'] diff --git a/packages/client/lib/commands/CLIENT_LIST.ts b/packages/client/lib/commands/CLIENT_LIST.ts index dc43fb8855..1e7f3d9ab4 100644 --- a/packages/client/lib/commands/CLIENT_LIST.ts +++ b/packages/client/lib/commands/CLIENT_LIST.ts @@ -1,5 +1,5 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, VerbatimStringReply, Command } from '../RESP/types'; -import { pushVariadicArguments } from './generic-transformers'; import CLIENT_INFO, { ClientInfoReply } from './CLIENT_INFO'; export interface ListFilterType { @@ -15,21 +15,18 @@ export interface ListFilterId { export type ListFilter = ListFilterType | ListFilterId; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(filter?: ListFilter) { - let args: Array = ['CLIENT', 'LIST']; - + parseCommand(parser: CommandParser, filter?: ListFilter) { + parser.push('CLIENT', 'LIST'); if (filter) { if (filter.TYPE !== undefined) { - args.push('TYPE', filter.TYPE); + parser.push('TYPE', filter.TYPE); } else { - args.push('ID'); - args = pushVariadicArguments(args, filter.ID); + parser.push('ID'); + parser.pushVariadic(filter.ID); } } - - return args; }, transformReply(rawReply: VerbatimStringReply): Array { const split = rawReply.toString().split('\n'), diff --git a/packages/client/lib/commands/CLIENT_NO-EVICT.spec.ts b/packages/client/lib/commands/CLIENT_NO-EVICT.spec.ts index 5de4dfd760..50afd41349 100644 --- a/packages/client/lib/commands/CLIENT_NO-EVICT.spec.ts +++ b/packages/client/lib/commands/CLIENT_NO-EVICT.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_NO_EVICT from './CLIENT_NO-EVICT'; +import { parseArgs } from './generic-transformers'; describe('CLIENT NO-EVICT', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('CLIENT NO-EVICT', () => { describe('transformArguments', () => { it('true', () => { assert.deepEqual( - CLIENT_NO_EVICT.transformArguments(true), + parseArgs(CLIENT_NO_EVICT, true), ['CLIENT', 'NO-EVICT', 'ON'] ); }); it('false', () => { assert.deepEqual( - CLIENT_NO_EVICT.transformArguments(false), + parseArgs(CLIENT_NO_EVICT, false), ['CLIENT', 'NO-EVICT', 'OFF'] ); }); diff --git a/packages/client/lib/commands/CLIENT_NO-EVICT.ts b/packages/client/lib/commands/CLIENT_NO-EVICT.ts index 82aa50074b..de2f65270e 100644 --- a/packages/client/lib/commands/CLIENT_NO-EVICT.ts +++ b/packages/client/lib/commands/CLIENT_NO-EVICT.ts @@ -1,14 +1,15 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(value: boolean) { - return [ + parseCommand(parser: CommandParser, value: boolean) { + parser.push( 'CLIENT', 'NO-EVICT', value ? 'ON' : 'OFF' - ]; + ); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_NO-TOUCH.spec.ts b/packages/client/lib/commands/CLIENT_NO-TOUCH.spec.ts index e58c22d9c6..ec5c9f18ae 100644 --- a/packages/client/lib/commands/CLIENT_NO-TOUCH.spec.ts +++ b/packages/client/lib/commands/CLIENT_NO-TOUCH.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_NO_TOUCH from './CLIENT_NO-TOUCH'; +import { parseArgs } from './generic-transformers'; describe('CLIENT NO-TOUCH', () => { testUtils.isVersionGreaterThanHook([7, 2]); @@ -8,14 +9,14 @@ describe('CLIENT NO-TOUCH', () => { describe('transformArguments', () => { it('true', () => { assert.deepEqual( - CLIENT_NO_TOUCH.transformArguments(true), + parseArgs(CLIENT_NO_TOUCH, true), ['CLIENT', 'NO-TOUCH', 'ON'] ); }); it('false', () => { assert.deepEqual( - CLIENT_NO_TOUCH.transformArguments(false), + parseArgs(CLIENT_NO_TOUCH, false), ['CLIENT', 'NO-TOUCH', 'OFF'] ); }); diff --git a/packages/client/lib/commands/CLIENT_NO-TOUCH.ts b/packages/client/lib/commands/CLIENT_NO-TOUCH.ts index a6fc5eb176..8c6deff4af 100644 --- a/packages/client/lib/commands/CLIENT_NO-TOUCH.ts +++ b/packages/client/lib/commands/CLIENT_NO-TOUCH.ts @@ -1,14 +1,15 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(value: boolean) { - return [ + parseCommand(parser: CommandParser, value: boolean) { + parser.push( 'CLIENT', 'NO-TOUCH', value ? 'ON' : 'OFF' - ]; + ); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_PAUSE.spec.ts b/packages/client/lib/commands/CLIENT_PAUSE.spec.ts index a30f907507..e213433afb 100644 --- a/packages/client/lib/commands/CLIENT_PAUSE.spec.ts +++ b/packages/client/lib/commands/CLIENT_PAUSE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_PAUSE from './CLIENT_PAUSE'; +import { parseArgs } from './generic-transformers'; describe('CLIENT PAUSE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLIENT_PAUSE.transformArguments(0), + parseArgs(CLIENT_PAUSE, 0), ['CLIENT', 'PAUSE', '0'] ); }); it('with mode', () => { assert.deepEqual( - CLIENT_PAUSE.transformArguments(0, 'ALL'), + parseArgs(CLIENT_PAUSE, 0, 'ALL'), ['CLIENT', 'PAUSE', '0', 'ALL'] ); }); diff --git a/packages/client/lib/commands/CLIENT_PAUSE.ts b/packages/client/lib/commands/CLIENT_PAUSE.ts index 87b4177ed8..ae6e437636 100644 --- a/packages/client/lib/commands/CLIENT_PAUSE.ts +++ b/packages/client/lib/commands/CLIENT_PAUSE.ts @@ -1,20 +1,14 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(timeout: number, mode?: 'WRITE' | 'ALL') { - const args = [ - 'CLIENT', - 'PAUSE', - timeout.toString() - ]; - + parseCommand(parser: CommandParser, timeout: number, mode?: 'WRITE' | 'ALL') { + parser.push('CLIENT', 'PAUSE', timeout.toString()); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_SETNAME.spec.ts b/packages/client/lib/commands/CLIENT_SETNAME.spec.ts index 8e6b914791..b2b339c3d1 100644 --- a/packages/client/lib/commands/CLIENT_SETNAME.spec.ts +++ b/packages/client/lib/commands/CLIENT_SETNAME.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_SETNAME from './CLIENT_SETNAME'; +import { parseArgs } from './generic-transformers'; describe('CLIENT SETNAME', () => { it('transformArguments', () => { assert.deepEqual( - CLIENT_SETNAME.transformArguments('name'), + parseArgs(CLIENT_SETNAME, 'name'), ['CLIENT', 'SETNAME', 'name'] ); }); diff --git a/packages/client/lib/commands/CLIENT_SETNAME.ts b/packages/client/lib/commands/CLIENT_SETNAME.ts index e2e2a92195..335891e830 100644 --- a/packages/client/lib/commands/CLIENT_SETNAME.ts +++ b/packages/client/lib/commands/CLIENT_SETNAME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(name: RedisArgument) { - return ['CLIENT', 'SETNAME', name]; + parseCommand(parser: CommandParser, name: RedisArgument) { + parser.push('CLIENT', 'SETNAME', name); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_TRACKING.spec.ts b/packages/client/lib/commands/CLIENT_TRACKING.spec.ts index 98fe091fb1..032725635e 100644 --- a/packages/client/lib/commands/CLIENT_TRACKING.spec.ts +++ b/packages/client/lib/commands/CLIENT_TRACKING.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_TRACKING from './CLIENT_TRACKING'; +import { parseArgs } from './generic-transformers'; describe('CLIENT TRACKING', () => { testUtils.isVersionGreaterThanHook([6]); @@ -9,14 +10,14 @@ describe('CLIENT TRACKING', () => { describe('true', () => { it('simple', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true), + parseArgs(CLIENT_TRACKING, true), ['CLIENT', 'TRACKING', 'ON'] ); }); it('with REDIRECT', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { REDIRECT: 1 }), ['CLIENT', 'TRACKING', 'ON', 'REDIRECT', '1'] @@ -26,7 +27,7 @@ describe('CLIENT TRACKING', () => { describe('with BCAST', () => { it('simple', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { BCAST: true }), ['CLIENT', 'TRACKING', 'ON', 'BCAST'] @@ -36,7 +37,7 @@ describe('CLIENT TRACKING', () => { describe('with PREFIX', () => { it('string', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { BCAST: true, PREFIX: 'prefix' }), @@ -46,7 +47,7 @@ describe('CLIENT TRACKING', () => { it('array', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { BCAST: true, PREFIX: ['1', '2'] }), @@ -58,7 +59,7 @@ describe('CLIENT TRACKING', () => { it('with OPTIN', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { OPTIN: true }), ['CLIENT', 'TRACKING', 'ON', 'OPTIN'] @@ -67,7 +68,7 @@ describe('CLIENT TRACKING', () => { it('with OPTOUT', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { OPTOUT: true }), ['CLIENT', 'TRACKING', 'ON', 'OPTOUT'] @@ -76,7 +77,7 @@ describe('CLIENT TRACKING', () => { it('with NOLOOP', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(true, { + parseArgs(CLIENT_TRACKING, true, { NOLOOP: true }), ['CLIENT', 'TRACKING', 'ON', 'NOLOOP'] @@ -86,7 +87,7 @@ describe('CLIENT TRACKING', () => { it('false', () => { assert.deepEqual( - CLIENT_TRACKING.transformArguments(false), + parseArgs(CLIENT_TRACKING, false), ['CLIENT', 'TRACKING', 'OFF'] ); }); diff --git a/packages/client/lib/commands/CLIENT_TRACKING.ts b/packages/client/lib/commands/CLIENT_TRACKING.ts index a783ce3589..df70a3705f 100644 --- a/packages/client/lib/commands/CLIENT_TRACKING.ts +++ b/packages/client/lib/commands/CLIENT_TRACKING.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { SimpleStringReply, Command } from '../RESP/types'; import { RedisVariadicArgument } from './generic-transformers'; interface CommonOptions { @@ -26,50 +27,49 @@ export type ClientTrackingOptions = CommonOptions & ( ); export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, mode: M, options?: M extends true ? ClientTrackingOptions : never ) { - const args: Array = [ + parser.push( 'CLIENT', 'TRACKING', mode ? 'ON' : 'OFF' - ]; + ); if (mode) { if (options?.REDIRECT) { - args.push( + parser.push( 'REDIRECT', options.REDIRECT.toString() ); } if (isBroadcast(options)) { - args.push('BCAST'); + parser.push('BCAST'); if (options?.PREFIX) { if (Array.isArray(options.PREFIX)) { for (const prefix of options.PREFIX) { - args.push('PREFIX', prefix); + parser.push('PREFIX', prefix); } } else { - args.push('PREFIX', options.PREFIX); + parser.push('PREFIX', options.PREFIX); } } } else if (isOptIn(options)) { - args.push('OPTIN'); + parser.push('OPTIN'); } else if (isOptOut(options)) { - args.push('OPTOUT'); + parser.push('OPTOUT'); } if (options?.NOLOOP) { - args.push('NOLOOP'); + parser.push('NOLOOP'); } } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLIENT_TRACKINGINFO.spec.ts b/packages/client/lib/commands/CLIENT_TRACKINGINFO.spec.ts index 1cefbd27d5..d776519df2 100644 --- a/packages/client/lib/commands/CLIENT_TRACKINGINFO.spec.ts +++ b/packages/client/lib/commands/CLIENT_TRACKINGINFO.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_TRACKINGINFO from './CLIENT_TRACKINGINFO'; +import { parseArgs } from './generic-transformers'; describe('CLIENT TRACKINGINFO', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - CLIENT_TRACKINGINFO.transformArguments(), + parseArgs(CLIENT_TRACKINGINFO), ['CLIENT', 'TRACKINGINFO'] ); }); diff --git a/packages/client/lib/commands/CLIENT_TRACKINGINFO.ts b/packages/client/lib/commands/CLIENT_TRACKINGINFO.ts index d969ba0219..fe6e090455 100644 --- a/packages/client/lib/commands/CLIENT_TRACKINGINFO.ts +++ b/packages/client/lib/commands/CLIENT_TRACKINGINFO.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { TuplesToMapReply, BlobStringReply, SetReply, NumberReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; type TrackingInfo = TuplesToMapReply<[ @@ -7,10 +8,10 @@ type TrackingInfo = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLIENT', 'TRACKINGINFO']; + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'TRACKINGINFO'); }, transformReply: { 2: (reply: UnwrapReply>) => ({ diff --git a/packages/client/lib/commands/CLIENT_UNPAUSE.spec.ts b/packages/client/lib/commands/CLIENT_UNPAUSE.spec.ts index bddf3ca0f0..0b58cf6517 100644 --- a/packages/client/lib/commands/CLIENT_UNPAUSE.spec.ts +++ b/packages/client/lib/commands/CLIENT_UNPAUSE.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLIENT_UNPAUSE from './CLIENT_UNPAUSE'; +import { parseArgs } from './generic-transformers'; describe('CLIENT UNPAUSE', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - CLIENT_UNPAUSE.transformArguments(), + parseArgs(CLIENT_UNPAUSE), ['CLIENT', 'UNPAUSE'] ); }); diff --git a/packages/client/lib/commands/CLIENT_UNPAUSE.ts b/packages/client/lib/commands/CLIENT_UNPAUSE.ts index 9da0a9a8bb..c202e50a5d 100644 --- a/packages/client/lib/commands/CLIENT_UNPAUSE.ts +++ b/packages/client/lib/commands/CLIENT_UNPAUSE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLIENT', 'UNPAUSE']; + parseCommand(parser: CommandParser) { + parser.push('CLIENT', 'UNPAUSE'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts index 56f7b2a85e..4a9b1839bb 100644 --- a/packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLUSTER_ADDSLOTS from './CLUSTER_ADDSLOTS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER ADDSLOTS', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - CLUSTER_ADDSLOTS.transformArguments(0), + parseArgs(CLUSTER_ADDSLOTS, 0), ['CLUSTER', 'ADDSLOTS', '0'] ); }); it('multiple', () => { assert.deepEqual( - CLUSTER_ADDSLOTS.transformArguments([0, 1]), + parseArgs(CLUSTER_ADDSLOTS, [0, 1]), ['CLUSTER', 'ADDSLOTS', '0', '1'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_ADDSLOTS.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTS.ts index dc42c2f13e..0f5c4513d1 100644 --- a/packages/client/lib/commands/CLUSTER_ADDSLOTS.ts +++ b/packages/client/lib/commands/CLUSTER_ADDSLOTS.ts @@ -1,14 +1,12 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; -import { pushVariadicNumberArguments } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(slots: number | Array) { - return pushVariadicNumberArguments( - ['CLUSTER', 'ADDSLOTS'], - slots - ); + parseCommand(parser: CommandParser, slots: number | Array) { + parser.push('CLUSTER', 'ADDSLOTS'); + parser.pushVariadicNumber(slots); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts index 6af6f586e9..40706968f9 100644 --- a/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts +++ b/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import CLUSTER_ADDSLOTSRANGE from './CLUSTER_ADDSLOTSRANGE'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER ADDSLOTSRANGE', () => { testUtils.isVersionGreaterThanHook([7, 0]); @@ -8,7 +9,7 @@ describe('CLUSTER ADDSLOTSRANGE', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - CLUSTER_ADDSLOTSRANGE.transformArguments({ + parseArgs(CLUSTER_ADDSLOTSRANGE, { start: 0, end: 1 }), @@ -18,7 +19,7 @@ describe('CLUSTER ADDSLOTSRANGE', () => { it('multiple', () => { assert.deepEqual( - CLUSTER_ADDSLOTSRANGE.transformArguments([{ + parseArgs(CLUSTER_ADDSLOTSRANGE, [{ start: 0, end: 1 }, { diff --git a/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts index 5cf649a30d..4078073198 100644 --- a/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts +++ b/packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; -import { pushSlotRangesArguments, SlotRange } from './generic-transformers'; +import { parseSlotRangesArguments, SlotRange } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(ranges: SlotRange | Array) { - return pushSlotRangesArguments( - ['CLUSTER', 'ADDSLOTSRANGE'], - ranges - ); + parseCommand(parser: CommandParser, ranges: SlotRange | Array) { + parser.push('CLUSTER', 'ADDSLOTSRANGE'); + parseSlotRangesArguments(parser, ranges); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts b/packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts index d21bc47c5d..f3ecde9f6a 100644 --- a/packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts +++ b/packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_BUMPEPOCH from './CLUSTER_BUMPEPOCH'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER BUMPEPOCH', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_BUMPEPOCH.transformArguments(), + parseArgs(CLUSTER_BUMPEPOCH), ['CLUSTER', 'BUMPEPOCH'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts b/packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts index 94f7e3b56f..04b62f8542 100644 --- a/packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts +++ b/packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'BUMPEPOCH']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'BUMPEPOCH'); }, transformReply: undefined as unknown as () => SimpleStringReply<'BUMPED' | 'STILL'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.spec.ts b/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.spec.ts index 93c2aca780..06a901ef30 100644 --- a/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_COUNT_FAILURE_REPORTS from './CLUSTER_COUNT-FAILURE-REPORTS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER COUNT-FAILURE-REPORTS', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_COUNT_FAILURE_REPORTS.transformArguments('0'), + parseArgs(CLUSTER_COUNT_FAILURE_REPORTS, '0'), ['CLUSTER', 'COUNT-FAILURE-REPORTS', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.ts b/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.ts index a005694713..0ac311f7ec 100644 --- a/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.ts +++ b/packages/client/lib/commands/CLUSTER_COUNT-FAILURE-REPORTS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(nodeId: RedisArgument) { - return ['CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId]; + parseCommand(parser: CommandParser, nodeId: RedisArgument) { + parser.push('CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts index 180a120e15..5284840946 100644 --- a/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts +++ b/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_COUNTKEYSINSLOT from './CLUSTER_COUNTKEYSINSLOT'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER COUNTKEYSINSLOT', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_COUNTKEYSINSLOT.transformArguments(0), + parseArgs(CLUSTER_COUNTKEYSINSLOT, 0), ['CLUSTER', 'COUNTKEYSINSLOT', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts b/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts index 61f46230e8..63b4a8e02e 100644 --- a/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts +++ b/packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(slot: number) { - return ['CLUSTER', 'COUNTKEYSINSLOT', slot.toString()]; + parseCommand(parser: CommandParser, slot: number) { + parser.push('CLUSTER', 'COUNTKEYSINSLOT', slot.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts index 59e40217b9..2937fdd4d7 100644 --- a/packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLUSTER_DELSLOTS from './CLUSTER_DELSLOTS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER DELSLOTS', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - CLUSTER_DELSLOTS.transformArguments(0), + parseArgs(CLUSTER_DELSLOTS, 0), ['CLUSTER', 'DELSLOTS', '0'] ); }); it('multiple', () => { assert.deepEqual( - CLUSTER_DELSLOTS.transformArguments([0, 1]), + parseArgs(CLUSTER_DELSLOTS, [0, 1]), ['CLUSTER', 'DELSLOTS', '0', '1'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_DELSLOTS.ts b/packages/client/lib/commands/CLUSTER_DELSLOTS.ts index 6a6bbb7608..9be6e962a1 100644 --- a/packages/client/lib/commands/CLUSTER_DELSLOTS.ts +++ b/packages/client/lib/commands/CLUSTER_DELSLOTS.ts @@ -1,14 +1,12 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; -import { pushVariadicNumberArguments } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(slots: number | Array) { - return pushVariadicNumberArguments( - ['CLUSTER', 'DELSLOTS'], - slots - ); + parseCommand(parser: CommandParser, slots: number | Array) { + parser.push('CLUSTER', 'DELSLOTS'); + parser.pushVariadicNumber(slots); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts b/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts index 2615f394b8..6007421d11 100644 --- a/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts +++ b/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import CLUSTER_DELSLOTSRANGE from './CLUSTER_DELSLOTSRANGE'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER DELSLOTSRANGE', () => { describe('transformArguments', () => { it('single', () => { assert.deepEqual( - CLUSTER_DELSLOTSRANGE.transformArguments({ + parseArgs(CLUSTER_DELSLOTSRANGE, { start: 0, end: 1 }), @@ -15,7 +16,7 @@ describe('CLUSTER DELSLOTSRANGE', () => { it('multiple', () => { assert.deepEqual( - CLUSTER_DELSLOTSRANGE.transformArguments([{ + parseArgs(CLUSTER_DELSLOTSRANGE, [{ start: 0, end: 1 }, { diff --git a/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts b/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts index e28ca9c840..64c04021ba 100644 --- a/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts +++ b/packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; -import { pushSlotRangesArguments, SlotRange } from './generic-transformers'; +import { parseSlotRangesArguments, SlotRange } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(ranges: SlotRange | Array) { - return pushSlotRangesArguments( - ['CLUSTER', 'DELSLOTSRANGE'], - ranges - ); + parseCommand(parser:CommandParser, ranges: SlotRange | Array) { + parser.push('CLUSTER', 'DELSLOTSRANGE'); + parseSlotRangesArguments(parser, ranges); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts b/packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts index ac18a9a7f8..f8e4b98604 100644 --- a/packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts +++ b/packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLUSTER_FAILOVER, { FAILOVER_MODES } from './CLUSTER_FAILOVER'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER FAILOVER', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLUSTER_FAILOVER.transformArguments(), + parseArgs(CLUSTER_FAILOVER), ['CLUSTER', 'FAILOVER'] ); }); it('with mode', () => { assert.deepEqual( - CLUSTER_FAILOVER.transformArguments({ + parseArgs(CLUSTER_FAILOVER, { mode: FAILOVER_MODES.FORCE }), ['CLUSTER', 'FAILOVER', 'FORCE'] diff --git a/packages/client/lib/commands/CLUSTER_FAILOVER.ts b/packages/client/lib/commands/CLUSTER_FAILOVER.ts index 63f79a246b..f74d65bd69 100644 --- a/packages/client/lib/commands/CLUSTER_FAILOVER.ts +++ b/packages/client/lib/commands/CLUSTER_FAILOVER.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export const FAILOVER_MODES = { @@ -12,16 +13,14 @@ export interface ClusterFailoverOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(options?: ClusterFailoverOptions) { - const args = ['CLUSTER', 'FAILOVER']; + parseCommand(parser:CommandParser, options?: ClusterFailoverOptions) { + parser.push('CLUSTER', 'FAILOVER'); if (options?.mode) { - args.push(options.mode); + parser.push(options.mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts index fbc4346136..43701adfe6 100644 --- a/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLUSTER_FLUSHSLOTS from './CLUSTER_FLUSHSLOTS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER FLUSHSLOTS', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_FLUSHSLOTS.transformArguments(), + parseArgs(CLUSTER_FLUSHSLOTS), ['CLUSTER', 'FLUSHSLOTS'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts index 327ed7b7d1..dab22b2e74 100644 --- a/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts +++ b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'FLUSHSLOTS']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'FLUSHSLOTS'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_FORGET.spec.ts b/packages/client/lib/commands/CLUSTER_FORGET.spec.ts index a9a923b01e..8d02374cf8 100644 --- a/packages/client/lib/commands/CLUSTER_FORGET.spec.ts +++ b/packages/client/lib/commands/CLUSTER_FORGET.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLUSTER_FORGET from './CLUSTER_FORGET'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER FORGET', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_FORGET.transformArguments('0'), + parseArgs(CLUSTER_FORGET, '0'), ['CLUSTER', 'FORGET', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_FORGET.ts b/packages/client/lib/commands/CLUSTER_FORGET.ts index a51c039563..2928c3e907 100644 --- a/packages/client/lib/commands/CLUSTER_FORGET.ts +++ b/packages/client/lib/commands/CLUSTER_FORGET.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(nodeId: RedisArgument) { - return ['CLUSTER', 'FORGET', nodeId]; + parseCommand(parser: CommandParser, nodeId: RedisArgument) { + parser.push('CLUSTER', 'FORGET', nodeId); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts index f1a4e2c3bc..468eecc74a 100644 --- a/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts +++ b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_GETKEYSINSLOT from './CLUSTER_GETKEYSINSLOT'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER GETKEYSINSLOT', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_GETKEYSINSLOT.transformArguments(0, 10), + parseArgs(CLUSTER_GETKEYSINSLOT, 0, 10), ['CLUSTER', 'GETKEYSINSLOT', '0', '10'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts index c19cd225e0..2fd630ea1a 100644 --- a/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts +++ b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(slot: number, count: number) { - return ['CLUSTER', 'GETKEYSINSLOT', slot.toString(), count.toString()]; + parseCommand(parser: CommandParser, slot: number, count: number) { + parser.push('CLUSTER', 'GETKEYSINSLOT', slot.toString(), count.toString()); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_INFO.spec.ts b/packages/client/lib/commands/CLUSTER_INFO.spec.ts index f7c708663f..01dafce8d5 100644 --- a/packages/client/lib/commands/CLUSTER_INFO.spec.ts +++ b/packages/client/lib/commands/CLUSTER_INFO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_INFO from './CLUSTER_INFO'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER INFO', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_INFO.transformArguments(), + parseArgs(CLUSTER_INFO), ['CLUSTER', 'INFO'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_INFO.ts b/packages/client/lib/commands/CLUSTER_INFO.ts index 4605efbe81..53140b3881 100644 --- a/packages/client/lib/commands/CLUSTER_INFO.ts +++ b/packages/client/lib/commands/CLUSTER_INFO.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { VerbatimStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'INFO']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'INFO'); }, transformReply: undefined as unknown as () => VerbatimStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts index d582c616cd..188c403abb 100644 --- a/packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts +++ b/packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_KEYSLOT from './CLUSTER_KEYSLOT'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER KEYSLOT', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_KEYSLOT.transformArguments('key'), + parseArgs(CLUSTER_KEYSLOT, 'key'), ['CLUSTER', 'KEYSLOT', 'key'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_KEYSLOT.ts b/packages/client/lib/commands/CLUSTER_KEYSLOT.ts index 81e8443011..d81a14e1a9 100644 --- a/packages/client/lib/commands/CLUSTER_KEYSLOT.ts +++ b/packages/client/lib/commands/CLUSTER_KEYSLOT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { Command, NumberReply, RedisArgument } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['CLUSTER', 'KEYSLOT', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('CLUSTER', 'KEYSLOT', key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_LINKS.spec.ts b/packages/client/lib/commands/CLUSTER_LINKS.spec.ts index d94231634e..609ecfd3da 100644 --- a/packages/client/lib/commands/CLUSTER_LINKS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_LINKS.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_LINKS from './CLUSTER_LINKS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER LINKS', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - CLUSTER_LINKS.transformArguments(), + parseArgs(CLUSTER_LINKS), ['CLUSTER', 'LINKS'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_LINKS.ts b/packages/client/lib/commands/CLUSTER_LINKS.ts index df83f3f7a1..e98f61e762 100644 --- a/packages/client/lib/commands/CLUSTER_LINKS.ts +++ b/packages/client/lib/commands/CLUSTER_LINKS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; type ClusterLinksReply = ArrayReply>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'LINKS']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'LINKS'); }, transformReply: { 2: (reply: UnwrapReply>) => reply.map(link => { diff --git a/packages/client/lib/commands/CLUSTER_MEET.spec.ts b/packages/client/lib/commands/CLUSTER_MEET.spec.ts index 0b678f009f..6c063f34e4 100644 --- a/packages/client/lib/commands/CLUSTER_MEET.spec.ts +++ b/packages/client/lib/commands/CLUSTER_MEET.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLUSTER_MEET from './CLUSTER_MEET'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER MEET', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_MEET.transformArguments('127.0.0.1', 6379), + parseArgs(CLUSTER_MEET, '127.0.0.1', 6379), ['CLUSTER', 'MEET', '127.0.0.1', '6379'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_MEET.ts b/packages/client/lib/commands/CLUSTER_MEET.ts index df72599d40..804e5963d1 100644 --- a/packages/client/lib/commands/CLUSTER_MEET.ts +++ b/packages/client/lib/commands/CLUSTER_MEET.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(host: string, port: number) { - return ['CLUSTER', 'MEET', host, port.toString()]; + parseCommand(parser: CommandParser, host: string, port: number) { + parser.push('CLUSTER', 'MEET', host, port.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_MYID.spec.ts b/packages/client/lib/commands/CLUSTER_MYID.spec.ts index 74540e98ab..78bb4495e3 100644 --- a/packages/client/lib/commands/CLUSTER_MYID.spec.ts +++ b/packages/client/lib/commands/CLUSTER_MYID.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_MYID from './CLUSTER_MYID'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER MYID', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_MYID.transformArguments(), + parseArgs(CLUSTER_MYID), ['CLUSTER', 'MYID'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_MYID.ts b/packages/client/lib/commands/CLUSTER_MYID.ts index 73711b47eb..2aae7cdd8e 100644 --- a/packages/client/lib/commands/CLUSTER_MYID.ts +++ b/packages/client/lib/commands/CLUSTER_MYID.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'MYID']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'MYID'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_MYSHARDID.spec.ts b/packages/client/lib/commands/CLUSTER_MYSHARDID.spec.ts index e64f2e3777..6c2a61801b 100644 --- a/packages/client/lib/commands/CLUSTER_MYSHARDID.spec.ts +++ b/packages/client/lib/commands/CLUSTER_MYSHARDID.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_MYSHARDID from './CLUSTER_MYSHARDID'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER MYSHARDID', () => { testUtils.isVersionGreaterThanHook([7, 2]); it('transformArguments', () => { assert.deepEqual( - CLUSTER_MYSHARDID.transformArguments(), + parseArgs(CLUSTER_MYSHARDID), ['CLUSTER', 'MYSHARDID'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_MYSHARDID.ts b/packages/client/lib/commands/CLUSTER_MYSHARDID.ts index 0c38b61634..ccde3ee249 100644 --- a/packages/client/lib/commands/CLUSTER_MYSHARDID.ts +++ b/packages/client/lib/commands/CLUSTER_MYSHARDID.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'MYSHARDID']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'MYSHARDID'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_NODES.spec.ts b/packages/client/lib/commands/CLUSTER_NODES.spec.ts index 99db17a23e..a49996586b 100644 --- a/packages/client/lib/commands/CLUSTER_NODES.spec.ts +++ b/packages/client/lib/commands/CLUSTER_NODES.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_NODES from './CLUSTER_NODES'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER NODES', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_NODES.transformArguments(), + parseArgs(CLUSTER_NODES), ['CLUSTER', 'NODES'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_NODES.ts b/packages/client/lib/commands/CLUSTER_NODES.ts index 64dd505623..c8b59f8822 100644 --- a/packages/client/lib/commands/CLUSTER_NODES.ts +++ b/packages/client/lib/commands/CLUSTER_NODES.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { VerbatimStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'NODES']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'NODES'); }, transformReply: undefined as unknown as () => VerbatimStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts b/packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts index 1a48f36088..11bf086bb6 100644 --- a/packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_REPLICAS from './CLUSTER_REPLICAS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER REPLICAS', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_REPLICAS.transformArguments('0'), + parseArgs(CLUSTER_REPLICAS, '0'), ['CLUSTER', 'REPLICAS', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_REPLICAS.ts b/packages/client/lib/commands/CLUSTER_REPLICAS.ts index 8e0fe2cdfd..eb60e560b4 100644 --- a/packages/client/lib/commands/CLUSTER_REPLICAS.ts +++ b/packages/client/lib/commands/CLUSTER_REPLICAS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(nodeId: RedisArgument) { - return ['CLUSTER', 'REPLICAS', nodeId]; + parseCommand(parser: CommandParser, nodeId: RedisArgument) { + parser.push('CLUSTER', 'REPLICAS', nodeId); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts b/packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts index 80935385a8..3f130d360b 100644 --- a/packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts +++ b/packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLUSTER_REPLICATE from './CLUSTER_REPLICATE'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER REPLICATE', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_REPLICATE.transformArguments('0'), + parseArgs(CLUSTER_REPLICATE, '0'), ['CLUSTER', 'REPLICATE', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_REPLICATE.ts b/packages/client/lib/commands/CLUSTER_REPLICATE.ts index 7431142024..d7312ae108 100644 --- a/packages/client/lib/commands/CLUSTER_REPLICATE.ts +++ b/packages/client/lib/commands/CLUSTER_REPLICATE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(nodeId: RedisArgument) { - return ['CLUSTER', 'REPLICATE', nodeId]; + parseCommand(parser: CommandParser, nodeId: RedisArgument) { + parser.push('CLUSTER', 'REPLICATE', nodeId); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_RESET.spec.ts b/packages/client/lib/commands/CLUSTER_RESET.spec.ts index 190bdaf69e..1ef55e3f57 100644 --- a/packages/client/lib/commands/CLUSTER_RESET.spec.ts +++ b/packages/client/lib/commands/CLUSTER_RESET.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLUSTER_RESET from './CLUSTER_RESET'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER RESET', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLUSTER_RESET.transformArguments(), + parseArgs(CLUSTER_RESET), ['CLUSTER', 'RESET'] ); }); it('with mode', () => { assert.deepEqual( - CLUSTER_RESET.transformArguments({ + parseArgs(CLUSTER_RESET, { mode: 'HARD' }), ['CLUSTER', 'RESET', 'HARD'] diff --git a/packages/client/lib/commands/CLUSTER_RESET.ts b/packages/client/lib/commands/CLUSTER_RESET.ts index 7aaac9d3b0..2ba1a6eaf2 100644 --- a/packages/client/lib/commands/CLUSTER_RESET.ts +++ b/packages/client/lib/commands/CLUSTER_RESET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export interface ClusterResetOptions { @@ -5,16 +6,14 @@ export interface ClusterResetOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(options?: ClusterResetOptions) { - const args = ['CLUSTER', 'RESET']; + parseCommand(parser: CommandParser, options?: ClusterResetOptions) { + parser.push('CLUSTER', 'RESET'); if (options?.mode) { - args.push(options.mode); + parser.push(options.mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts b/packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts index ece8087e8e..a0d317ffae 100644 --- a/packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts +++ b/packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_SAVECONFIG from './CLUSTER_SAVECONFIG'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER SAVECONFIG', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_SAVECONFIG.transformArguments(), + parseArgs(CLUSTER_SAVECONFIG), ['CLUSTER', 'SAVECONFIG'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_SAVECONFIG.ts b/packages/client/lib/commands/CLUSTER_SAVECONFIG.ts index 489ffd27e4..08da2a45b8 100644 --- a/packages/client/lib/commands/CLUSTER_SAVECONFIG.ts +++ b/packages/client/lib/commands/CLUSTER_SAVECONFIG.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'SAVECONFIG']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'SAVECONFIG'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.spec.ts b/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.spec.ts index 39cf026d0e..fb02ee2fe6 100644 --- a/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.spec.ts +++ b/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CLUSTER_SET_CONFIG_EPOCH from './CLUSTER_SET-CONFIG-EPOCH'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER SET-CONFIG-EPOCH', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_SET_CONFIG_EPOCH.transformArguments(0), + parseArgs(CLUSTER_SET_CONFIG_EPOCH, 0), ['CLUSTER', 'SET-CONFIG-EPOCH', '0'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts b/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts index 2a650840c4..ba423df7fb 100644 --- a/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts +++ b/packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(configEpoch: number) { - return ['CLUSTER', 'SET-CONFIG-EPOCH', configEpoch.toString() ]; + parseCommand(parser: CommandParser, configEpoch: number) { + parser.push('CLUSTER', 'SET-CONFIG-EPOCH', configEpoch.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts index 7bce6d74b4..fac496c3af 100644 --- a/packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts +++ b/packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import CLUSTER_SETSLOT, { CLUSTER_SLOT_STATES } from './CLUSTER_SETSLOT'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER SETSLOT', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLUSTER_SETSLOT.transformArguments(0, CLUSTER_SLOT_STATES.IMPORTING), + parseArgs(CLUSTER_SETSLOT, 0, CLUSTER_SLOT_STATES.IMPORTING), ['CLUSTER', 'SETSLOT', '0', 'IMPORTING'] ); }); it('with nodeId', () => { assert.deepEqual( - CLUSTER_SETSLOT.transformArguments(0, CLUSTER_SLOT_STATES.IMPORTING, 'nodeId'), + parseArgs(CLUSTER_SETSLOT, 0, CLUSTER_SLOT_STATES.IMPORTING, 'nodeId'), ['CLUSTER', 'SETSLOT', '0', 'IMPORTING', 'nodeId'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_SETSLOT.ts b/packages/client/lib/commands/CLUSTER_SETSLOT.ts index ad04513688..1f74316a3f 100644 --- a/packages/client/lib/commands/CLUSTER_SETSLOT.ts +++ b/packages/client/lib/commands/CLUSTER_SETSLOT.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export const CLUSTER_SLOT_STATES = { @@ -10,16 +11,14 @@ export const CLUSTER_SLOT_STATES = { export type ClusterSlotState = typeof CLUSTER_SLOT_STATES[keyof typeof CLUSTER_SLOT_STATES]; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(slot: number, state: ClusterSlotState, nodeId?: RedisArgument) { - const args: Array = ['CLUSTER', 'SETSLOT', slot.toString(), state]; + parseCommand(parser: CommandParser, slot: number, state: ClusterSlotState, nodeId?: RedisArgument) { + parser.push('CLUSTER', 'SETSLOT', slot.toString(), state); if (nodeId) { - args.push(nodeId); + parser.push(nodeId); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/CLUSTER_SLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_SLOTS.spec.ts index 198dfdc6c1..28879b036a 100644 --- a/packages/client/lib/commands/CLUSTER_SLOTS.spec.ts +++ b/packages/client/lib/commands/CLUSTER_SLOTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLUSTER_SLOTS from './CLUSTER_SLOTS'; +import { parseArgs } from './generic-transformers'; describe('CLUSTER SLOTS', () => { it('transformArguments', () => { assert.deepEqual( - CLUSTER_SLOTS.transformArguments(), + parseArgs(CLUSTER_SLOTS), ['CLUSTER', 'SLOTS'] ); }); diff --git a/packages/client/lib/commands/CLUSTER_SLOTS.ts b/packages/client/lib/commands/CLUSTER_SLOTS.ts index 1b523328bb..f6f967abe2 100644 --- a/packages/client/lib/commands/CLUSTER_SLOTS.ts +++ b/packages/client/lib/commands/CLUSTER_SLOTS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { TuplesReply, BlobStringReply, NumberReply, ArrayReply, UnwrapReply, Command } from '../RESP/types'; type RawNode = TuplesReply<[ @@ -16,10 +17,10 @@ type ClusterSlotsRawReply = ArrayReply<[ export type ClusterSlotsNode = ReturnType; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CLUSTER', 'SLOTS']; + parseCommand(parser: CommandParser) { + parser.push('CLUSTER', 'SLOTS'); }, transformReply(reply: UnwrapReply) { return reply.map(([from, to, master, ...replicas]) => ({ diff --git a/packages/client/lib/commands/COMMAND.ts b/packages/client/lib/commands/COMMAND.ts index d9a960107a..52eb7eb2fe 100644 --- a/packages/client/lib/commands/COMMAND.ts +++ b/packages/client/lib/commands/COMMAND.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, UnwrapReply } from '../RESP/types'; import { CommandRawReply, CommandReply, transformCommandReply } from './generic-transformers'; export default { + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['COMMAND']; + parseCommand(parser: CommandParser) { + parser.push('COMMAND'); }, // TODO: This works, as we don't currently handle any of the items returned as a map transformReply(reply: UnwrapReply>): Array { diff --git a/packages/client/lib/commands/COMMAND_COUNT.spec.ts b/packages/client/lib/commands/COMMAND_COUNT.spec.ts index 05bd29f223..a36091df48 100644 --- a/packages/client/lib/commands/COMMAND_COUNT.spec.ts +++ b/packages/client/lib/commands/COMMAND_COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import COMMAND_COUNT from './COMMAND_COUNT'; +import { parseArgs } from './generic-transformers'; describe('COMMAND COUNT', () => { it('transformArguments', () => { assert.deepEqual( - COMMAND_COUNT.transformArguments(), + parseArgs(COMMAND_COUNT), ['COMMAND', 'COUNT'] ); }); diff --git a/packages/client/lib/commands/COMMAND_COUNT.ts b/packages/client/lib/commands/COMMAND_COUNT.ts index 10b0fdefe0..ef561920b0 100644 --- a/packages/client/lib/commands/COMMAND_COUNT.ts +++ b/packages/client/lib/commands/COMMAND_COUNT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['COMMAND', 'COUNT']; + parseCommand(parser: CommandParser) { + parser.push('COMMAND', 'COUNT'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/COMMAND_GETKEYS.spec.ts b/packages/client/lib/commands/COMMAND_GETKEYS.spec.ts index d5b9f60790..332e2d51fb 100644 --- a/packages/client/lib/commands/COMMAND_GETKEYS.spec.ts +++ b/packages/client/lib/commands/COMMAND_GETKEYS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import COMMAND_GETKEYS from './COMMAND_GETKEYS'; +import { parseArgs } from './generic-transformers'; describe('COMMAND GETKEYS', () => { it('transformArguments', () => { assert.deepEqual( - COMMAND_GETKEYS.transformArguments(['GET', 'key']), + parseArgs(COMMAND_GETKEYS, ['GET', 'key']), ['COMMAND', 'GETKEYS', 'GET', 'key'] ); }); diff --git a/packages/client/lib/commands/COMMAND_GETKEYS.ts b/packages/client/lib/commands/COMMAND_GETKEYS.ts index 55cca415b8..97c5cb69ce 100644 --- a/packages/client/lib/commands/COMMAND_GETKEYS.ts +++ b/packages/client/lib/commands/COMMAND_GETKEYS.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(args: Array) { - return ['COMMAND', 'GETKEYS', ...args]; + parseCommand(parser: CommandParser, args: Array) { + parser.push('COMMAND', 'GETKEYS'); + parser.push(...args); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts b/packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts index a032190c16..72c1e16a2d 100644 --- a/packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts +++ b/packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, SetReply, UnwrapReply, Command } from '../RESP/types'; export type CommandGetKeysAndFlagsRawReply = ArrayReply>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(args: Array) { - return ['COMMAND', 'GETKEYSANDFLAGS', ...args]; + parseCommand(parser: CommandParser, args: Array) { + parser.push('COMMAND', 'GETKEYSANDFLAGS'); + parser.push(...args); }, transformReply(reply: UnwrapReply) { return reply.map(entry => { diff --git a/packages/client/lib/commands/COMMAND_INFO.ts b/packages/client/lib/commands/COMMAND_INFO.ts index 5dbd00e805..fdf0378065 100644 --- a/packages/client/lib/commands/COMMAND_INFO.ts +++ b/packages/client/lib/commands/COMMAND_INFO.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, UnwrapReply } from '../RESP/types'; import { CommandRawReply, CommandReply, transformCommandReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(commands: Array) { - return ['COMMAND', 'INFO', ...commands]; + parseCommand(parser: CommandParser, commands: Array) { + parser.push('COMMAND', 'INFO', ...commands); }, // TODO: This works, as we don't currently handle any of the items returned as a map transformReply(reply: UnwrapReply>): Array { diff --git a/packages/client/lib/commands/COMMAND_LIST.spec.ts b/packages/client/lib/commands/COMMAND_LIST.spec.ts index 28a9a203bc..d2ee9e6616 100644 --- a/packages/client/lib/commands/COMMAND_LIST.spec.ts +++ b/packages/client/lib/commands/COMMAND_LIST.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import COMMAND_LIST from './COMMAND_LIST'; +import { parseArgs } from './generic-transformers'; describe('COMMAND LIST', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,7 +9,7 @@ describe('COMMAND LIST', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - COMMAND_LIST.transformArguments(), + parseArgs(COMMAND_LIST), ['COMMAND', 'LIST'] ); }); @@ -16,7 +17,7 @@ describe('COMMAND LIST', () => { describe('with FILTERBY', () => { it('MODULE', () => { assert.deepEqual( - COMMAND_LIST.transformArguments({ + parseArgs(COMMAND_LIST, { FILTERBY: { type: 'MODULE', value: 'JSON' @@ -28,7 +29,7 @@ describe('COMMAND LIST', () => { it('ACLCAT', () => { assert.deepEqual( - COMMAND_LIST.transformArguments({ + parseArgs(COMMAND_LIST, { FILTERBY: { type: 'ACLCAT', value: 'admin' @@ -40,7 +41,7 @@ describe('COMMAND LIST', () => { it('PATTERN', () => { assert.deepEqual( - COMMAND_LIST.transformArguments({ + parseArgs(COMMAND_LIST, { FILTERBY: { type: 'PATTERN', value: 'a*' diff --git a/packages/client/lib/commands/COMMAND_LIST.ts b/packages/client/lib/commands/COMMAND_LIST.ts index e73cfdc1a0..ba518b70ec 100644 --- a/packages/client/lib/commands/COMMAND_LIST.ts +++ b/packages/client/lib/commands/COMMAND_LIST.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export const COMMAND_LIST_FILTER_BY = { @@ -16,20 +17,18 @@ export interface CommandListOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(options?: CommandListOptions) { - const args: Array = ['COMMAND', 'LIST']; + parseCommand(parser: CommandParser, options?: CommandListOptions) { + parser.push('COMMAND', 'LIST'); if (options?.FILTERBY) { - args.push( + parser.push( 'FILTERBY', options.FILTERBY.type, options.FILTERBY.value ); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CONFIG_GET.spec.ts b/packages/client/lib/commands/CONFIG_GET.spec.ts index 94bb2fadcb..411b2ddf47 100644 --- a/packages/client/lib/commands/CONFIG_GET.spec.ts +++ b/packages/client/lib/commands/CONFIG_GET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_GET from './CONFIG_GET'; +import { parseArgs } from './generic-transformers'; describe('CONFIG GET', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - CONFIG_GET.transformArguments('*'), + parseArgs(CONFIG_GET, '*'), ['CONFIG', 'GET', '*'] ); }); it('Array', () => { assert.deepEqual( - CONFIG_GET.transformArguments(['1', '2']), + parseArgs(CONFIG_GET, ['1', '2']), ['CONFIG', 'GET', '1', '2'] ); }); diff --git a/packages/client/lib/commands/CONFIG_GET.ts b/packages/client/lib/commands/CONFIG_GET.ts index 72fb6e56f5..54fa997bf6 100644 --- a/packages/client/lib/commands/CONFIG_GET.ts +++ b/packages/client/lib/commands/CONFIG_GET.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { MapReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments, transformTuplesReply } from './generic-transformers'; +import { RedisVariadicArgument, transformTuplesReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(parameters: RedisVariadicArgument) { - return pushVariadicArguments(['CONFIG', 'GET'], parameters); + parseCommand(parser: CommandParser, parameters: RedisVariadicArgument) { + parser.push('CONFIG', 'GET'); + parser.pushVariadic(parameters); }, transformReply: { 2: transformTuplesReply, diff --git a/packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts b/packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts index c0699e182f..f2f573df0d 100644 --- a/packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts +++ b/packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CONFIG_RESETSTAT from './CONFIG_RESETSTAT'; +import { parseArgs } from './generic-transformers'; describe('CONFIG RESETSTAT', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_RESETSTAT.transformArguments(), + parseArgs(CONFIG_RESETSTAT), ['CONFIG', 'RESETSTAT'] ); }); diff --git a/packages/client/lib/commands/CONFIG_RESETSTAT.ts b/packages/client/lib/commands/CONFIG_RESETSTAT.ts index 4d5deb18b4..15de5ba780 100644 --- a/packages/client/lib/commands/CONFIG_RESETSTAT.ts +++ b/packages/client/lib/commands/CONFIG_RESETSTAT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CONFIG', 'RESETSTAT']; + parseCommand(parser: CommandParser) { + parser.push('CONFIG', 'RESETSTAT'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CONFIG_REWRITE.spec.ts b/packages/client/lib/commands/CONFIG_REWRITE.spec.ts index d612ae216b..bc006e84c8 100644 --- a/packages/client/lib/commands/CONFIG_REWRITE.spec.ts +++ b/packages/client/lib/commands/CONFIG_REWRITE.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import CONFIG_REWRITE from './CONFIG_REWRITE'; +import { parseArgs } from './generic-transformers'; describe('CONFIG REWRITE', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_REWRITE.transformArguments(), + parseArgs(CONFIG_REWRITE), ['CONFIG', 'REWRITE'] ); }); diff --git a/packages/client/lib/commands/CONFIG_REWRITE.ts b/packages/client/lib/commands/CONFIG_REWRITE.ts index 6fbc4b1fa2..ae6712ffb5 100644 --- a/packages/client/lib/commands/CONFIG_REWRITE.ts +++ b/packages/client/lib/commands/CONFIG_REWRITE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['CONFIG', 'REWRITE']; + parseCommand(parser: CommandParser) { + parser.push('CONFIG', 'REWRITE'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/CONFIG_SET.spec.ts b/packages/client/lib/commands/CONFIG_SET.spec.ts index 060183f58d..56bed2ac46 100644 --- a/packages/client/lib/commands/CONFIG_SET.spec.ts +++ b/packages/client/lib/commands/CONFIG_SET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_SET from './CONFIG_SET'; +import { parseArgs } from './generic-transformers'; describe('CONFIG SET', () => { describe('transformArguments', () => { it('set one parameter (old version)', () => { assert.deepEqual( - CONFIG_SET.transformArguments('parameter', 'value'), + parseArgs(CONFIG_SET, 'parameter', 'value'), ['CONFIG', 'SET', 'parameter', 'value'] ); }); it('set muiltiple parameters', () => { assert.deepEqual( - CONFIG_SET.transformArguments({ + parseArgs(CONFIG_SET, { 1: 'a', 2: 'b', 3: 'c' diff --git a/packages/client/lib/commands/CONFIG_SET.ts b/packages/client/lib/commands/CONFIG_SET.ts index c7072245e2..dd1bbc29ef 100644 --- a/packages/client/lib/commands/CONFIG_SET.ts +++ b/packages/client/lib/commands/CONFIG_SET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command, RedisArgument } from '../RESP/types'; type SingleParameter = [parameter: RedisArgument, value: RedisArgument]; @@ -5,22 +6,21 @@ type SingleParameter = [parameter: RedisArgument, value: RedisArgument]; type MultipleParameters = [config: Record]; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, ...[parameterOrConfig, value]: SingleParameter | MultipleParameters ) { - const args: Array = ['CONFIG', 'SET']; + parser.push('CONFIG', 'SET'); if (typeof parameterOrConfig === 'string' || parameterOrConfig instanceof Buffer) { - args.push(parameterOrConfig, value!); + parser.push(parameterOrConfig, value!); } else { for (const [key, value] of Object.entries(parameterOrConfig)) { - args.push(key, value); + parser.push(key, value); } } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/COPY.spec.ts b/packages/client/lib/commands/COPY.spec.ts index c4c26c30dc..cd0c6ec9fb 100644 --- a/packages/client/lib/commands/COPY.spec.ts +++ b/packages/client/lib/commands/COPY.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import COPY from './COPY'; +import { parseArgs } from './generic-transformers'; describe('COPY', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('COPY', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - COPY.transformArguments('source', 'destination'), + parseArgs(COPY, 'source', 'destination'), ['COPY', 'source', 'destination'] ); }); it('with destination DB flag', () => { assert.deepEqual( - COPY.transformArguments('source', 'destination', { + parseArgs(COPY, 'source', 'destination', { DB: 1 }), ['COPY', 'source', 'destination', 'DB', '1'] @@ -24,7 +25,7 @@ describe('COPY', () => { it('with replace flag', () => { assert.deepEqual( - COPY.transformArguments('source', 'destination', { + parseArgs(COPY, 'source', 'destination', { REPLACE: true }), ['COPY', 'source', 'destination', 'REPLACE'] @@ -33,7 +34,7 @@ describe('COPY', () => { it('with both flags', () => { assert.deepEqual( - COPY.transformArguments('source', 'destination', { + parseArgs(COPY, 'source', 'destination', { DB: 1, REPLACE: true }), diff --git a/packages/client/lib/commands/COPY.ts b/packages/client/lib/commands/COPY.ts index a65948cf94..f26a930264 100644 --- a/packages/client/lib/commands/COPY.ts +++ b/packages/client/lib/commands/COPY.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export interface CopyCommandOptions { @@ -6,20 +7,18 @@ export interface CopyCommandOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(source: RedisArgument, destination: RedisArgument, options?: CopyCommandOptions) { - const args = ['COPY', source, destination]; + parseCommand(parser: CommandParser, source: RedisArgument, destination: RedisArgument, options?: CopyCommandOptions) { + parser.push('COPY'); + parser.pushKeys([source, destination]); if (options?.DB) { - args.push('DB', options.DB.toString()); + parser.push('DB', options.DB.toString()); } if (options?.REPLACE) { - args.push('REPLACE'); + parser.push('REPLACE'); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DBSIZE.spec.ts b/packages/client/lib/commands/DBSIZE.spec.ts index bd668d166e..5778e30de3 100644 --- a/packages/client/lib/commands/DBSIZE.spec.ts +++ b/packages/client/lib/commands/DBSIZE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DBSIZE from './DBSIZE'; +import { parseArgs } from './generic-transformers'; describe('DBSIZE', () => { it('transformArguments', () => { assert.deepEqual( - DBSIZE.transformArguments(), + parseArgs(DBSIZE), ['DBSIZE'] ); }); diff --git a/packages/client/lib/commands/DBSIZE.ts b/packages/client/lib/commands/DBSIZE.ts index 54770831ab..1ba1f06047 100644 --- a/packages/client/lib/commands/DBSIZE.ts +++ b/packages/client/lib/commands/DBSIZE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['DBSIZE']; + parseCommand(parser: CommandParser) { + parser.push('DBSIZE'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DECR.spec.ts b/packages/client/lib/commands/DECR.spec.ts index 80d6c8eb55..69ff5a5391 100644 --- a/packages/client/lib/commands/DECR.spec.ts +++ b/packages/client/lib/commands/DECR.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DECR from './DECR'; +import { parseArgs } from './generic-transformers'; describe('DECR', () => { it('transformArguments', () => { assert.deepEqual( - DECR.transformArguments('key'), + parseArgs(DECR, 'key'), ['DECR', 'key'] ); }); diff --git a/packages/client/lib/commands/DECR.ts b/packages/client/lib/commands/DECR.ts index 540148b7ee..b9a6200d81 100644 --- a/packages/client/lib/commands/DECR.ts +++ b/packages/client/lib/commands/DECR.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument) { - return ['DECR', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('DECR'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DECRBY.spec.ts b/packages/client/lib/commands/DECRBY.spec.ts index fc0c103318..ae80fd714e 100644 --- a/packages/client/lib/commands/DECRBY.spec.ts +++ b/packages/client/lib/commands/DECRBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DECRBY from './DECRBY'; +import { parseArgs } from './generic-transformers'; describe('DECRBY', () => { it('transformArguments', () => { assert.deepEqual( - DECRBY.transformArguments('key', 2), + parseArgs(DECRBY, 'key', 2), ['DECRBY', 'key', '2'] ); }); diff --git a/packages/client/lib/commands/DECRBY.ts b/packages/client/lib/commands/DECRBY.ts index 77d56939dd..53a8315130 100644 --- a/packages/client/lib/commands/DECRBY.ts +++ b/packages/client/lib/commands/DECRBY.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, decrement: number) { - return ['DECRBY', key, decrement.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, decrement: number) { + parser.push('DECRBY'); + parser.pushKey(key); + parser.push(decrement.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DEL.spec.ts b/packages/client/lib/commands/DEL.spec.ts index caac8ac13b..3d0364e752 100644 --- a/packages/client/lib/commands/DEL.spec.ts +++ b/packages/client/lib/commands/DEL.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DEL from './DEL'; +import { parseArgs } from './generic-transformers'; describe('DEL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - DEL.transformArguments('key'), + parseArgs(DEL, 'key'), ['DEL', 'key'] ); }); it('array', () => { assert.deepEqual( - DEL.transformArguments(['key1', 'key2']), + parseArgs(DEL, ['key1', 'key2']), ['DEL', 'key1', 'key2'] ); }); diff --git a/packages/client/lib/commands/DEL.ts b/packages/client/lib/commands/DEL.ts index f59a5ba2e8..da0803f4d1 100644 --- a/packages/client/lib/commands/DEL.ts +++ b/packages/client/lib/commands/DEL.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArguments(['DEL'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('DEL'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DISCARD.spec.ts b/packages/client/lib/commands/DISCARD.spec.ts index 76e0abd57a..7aa769fc2e 100644 --- a/packages/client/lib/commands/DISCARD.spec.ts +++ b/packages/client/lib/commands/DISCARD.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import DISCARD from './DISCARD'; +import { parseArgs } from './generic-transformers'; describe('DISCARD', () => { it('transformArguments', () => { assert.deepEqual( - DISCARD.transformArguments(), + parseArgs(DISCARD), ['DISCARD'] ); }); diff --git a/packages/client/lib/commands/DISCARD.ts b/packages/client/lib/commands/DISCARD.ts index e153070c98..1d30191c13 100644 --- a/packages/client/lib/commands/DISCARD.ts +++ b/packages/client/lib/commands/DISCARD.ts @@ -1,8 +1,9 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - transformArguments() { - return ['DISCARD']; + parseCommand(parser: CommandParser) { + parser.push('DISCARD'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/DUMP.spec.ts b/packages/client/lib/commands/DUMP.spec.ts index 15be3fae08..76fb2ec7c1 100644 --- a/packages/client/lib/commands/DUMP.spec.ts +++ b/packages/client/lib/commands/DUMP.spec.ts @@ -1,7 +1,16 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import DUMP from './DUMP'; +import { parseArgs } from './generic-transformers'; describe('DUMP', () => { + it('transformArguments', () => { + assert.deepEqual( + parseArgs(DUMP, 'key'), + ['DUMP', 'key'] + ); + }); + testUtils.testAll('client.dump', async client => { assert.equal( await client.dump('key'), diff --git a/packages/client/lib/commands/DUMP.ts b/packages/client/lib/commands/DUMP.ts index 06b12f06d0..e442c1cdb2 100644 --- a/packages/client/lib/commands/DUMP.ts +++ b/packages/client/lib/commands/DUMP.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['DUMP', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('DUMP'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ECHO.spec.ts b/packages/client/lib/commands/ECHO.spec.ts index c0d0725282..38fd1d4270 100644 --- a/packages/client/lib/commands/ECHO.spec.ts +++ b/packages/client/lib/commands/ECHO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ECHO from './ECHO'; +import { parseArgs } from './generic-transformers'; describe('ECHO', () => { it('transformArguments', () => { assert.deepEqual( - ECHO.transformArguments('message'), + parseArgs(ECHO, 'message'), ['ECHO', 'message'] ); }); diff --git a/packages/client/lib/commands/ECHO.ts b/packages/client/lib/commands/ECHO.ts index dfe5ec1300..7935bdc010 100644 --- a/packages/client/lib/commands/ECHO.ts +++ b/packages/client/lib/commands/ECHO.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(message: RedisArgument) { - return ['ECHO', message]; + parseCommand(parser: CommandParser, message: RedisArgument) { + parser.push('ECHO', message); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EVAL.spec.ts b/packages/client/lib/commands/EVAL.spec.ts index 2aea64e099..8ef16eed83 100644 --- a/packages/client/lib/commands/EVAL.spec.ts +++ b/packages/client/lib/commands/EVAL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EVAL from './EVAL'; +import { parseArgs } from './generic-transformers'; describe('EVAL', () => { it('transformArguments', () => { assert.deepEqual( - EVAL.transformArguments('return KEYS[1] + ARGV[1]', { + parseArgs(EVAL, 'return KEYS[1] + ARGV[1]', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/EVAL.ts b/packages/client/lib/commands/EVAL.ts index 21684e7a31..cdb8025b0b 100644 --- a/packages/client/lib/commands/EVAL.ts +++ b/packages/client/lib/commands/EVAL.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ReplyUnion, Command } from '../RESP/types'; export interface EvalOptions { @@ -5,29 +6,28 @@ export interface EvalOptions { arguments?: Array; } -export function transformEvalArguments( - command: RedisArgument, +export function parseEvalArguments( + parser: CommandParser, script: RedisArgument, options?: EvalOptions ) { - const args = [command, script]; - + parser.push(script); if (options?.keys) { - args.push(options.keys.length.toString(), ...options.keys); + parser.pushKeysLength(options.keys); } else { - args.push('0'); + parser.push('0'); } if (options?.arguments) { - args.push(...options.arguments); + parser.push(...options.arguments) } - - return args; } export default { - FIRST_KEY_INDEX: (_, options?: EvalOptions) => options?.keys?.[0], IS_READ_ONLY: false, - transformArguments: transformEvalArguments.bind(undefined, 'EVAL'), + parseCommand(...args: Parameters) { + args[0].push('EVAL'); + parseEvalArguments(...args); + }, transformReply: undefined as unknown as () => ReplyUnion } as const satisfies Command; diff --git a/packages/client/lib/commands/EVALSHA.spec.ts b/packages/client/lib/commands/EVALSHA.spec.ts index 81d3a0ec2b..c491d6e230 100644 --- a/packages/client/lib/commands/EVALSHA.spec.ts +++ b/packages/client/lib/commands/EVALSHA.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import EVALSHA from './EVALSHA'; +import { parseArgs } from './generic-transformers'; describe('EVALSHA', () => { it('transformArguments', () => { assert.deepEqual( - EVALSHA.transformArguments('sha1', { + parseArgs(EVALSHA, 'sha1', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/EVALSHA.ts b/packages/client/lib/commands/EVALSHA.ts index dc4127f90d..5a9cc77135 100644 --- a/packages/client/lib/commands/EVALSHA.ts +++ b/packages/client/lib/commands/EVALSHA.ts @@ -1,9 +1,11 @@ import { Command } from '../RESP/types'; -import EVAL, { transformEvalArguments } from './EVAL'; +import EVAL, { parseEvalArguments } from './EVAL'; export default { - FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, IS_READ_ONLY: false, - transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA'), + parseCommand(...args: Parameters) { + args[0].push('EVALSHA'); + parseEvalArguments(...args); + }, transformReply: EVAL.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EVALSHA_RO.spec.ts b/packages/client/lib/commands/EVALSHA_RO.spec.ts index 20b4a27e0d..d3debe933f 100644 --- a/packages/client/lib/commands/EVALSHA_RO.spec.ts +++ b/packages/client/lib/commands/EVALSHA_RO.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import EVALSHA_RO from './EVALSHA_RO'; +import { parseArgs } from './generic-transformers'; describe('EVALSHA_RO', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - EVALSHA_RO.transformArguments('sha1', { + parseArgs(EVALSHA_RO, 'sha1', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/EVALSHA_RO.ts b/packages/client/lib/commands/EVALSHA_RO.ts index fe9042bd5f..24fadb3f48 100644 --- a/packages/client/lib/commands/EVALSHA_RO.ts +++ b/packages/client/lib/commands/EVALSHA_RO.ts @@ -1,9 +1,11 @@ import { Command } from '../RESP/types'; -import EVAL, { transformEvalArguments } from './EVAL'; +import EVAL, { parseEvalArguments } from './EVAL'; export default { - FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, IS_READ_ONLY: true, - transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA_RO'), + parseCommand(...args: Parameters) { + args[0].push('EVALSHA_RO'); + parseEvalArguments(...args); + }, transformReply: EVAL.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EVAL_RO.spec.ts b/packages/client/lib/commands/EVAL_RO.spec.ts index 3f071e8068..b5cf1e4e92 100644 --- a/packages/client/lib/commands/EVAL_RO.spec.ts +++ b/packages/client/lib/commands/EVAL_RO.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EVAL_RO from './EVAL_RO'; +import { parseArgs } from './generic-transformers'; describe('EVAL_RO', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - EVAL_RO.transformArguments('return KEYS[1] + ARGV[1]', { + parseArgs(EVAL_RO, 'return KEYS[1] + ARGV[1]', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/EVAL_RO.ts b/packages/client/lib/commands/EVAL_RO.ts index 2608e28f78..2438fd9d1d 100644 --- a/packages/client/lib/commands/EVAL_RO.ts +++ b/packages/client/lib/commands/EVAL_RO.ts @@ -1,9 +1,11 @@ import { Command } from '../RESP/types'; -import EVAL, { transformEvalArguments } from './EVAL'; +import EVAL, { parseEvalArguments } from './EVAL'; export default { - FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, IS_READ_ONLY: true, - transformArguments: transformEvalArguments.bind(undefined, 'EVAL_RO'), + parseCommand(...args: Parameters) { + args[0].push('EVAL_RO'); + parseEvalArguments(...args); + }, transformReply: EVAL.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EXISTS.spec.ts b/packages/client/lib/commands/EXISTS.spec.ts index 695795697f..d2802dd49b 100644 --- a/packages/client/lib/commands/EXISTS.spec.ts +++ b/packages/client/lib/commands/EXISTS.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EXISTS from './EXISTS'; +import { parseArgs } from './generic-transformers'; describe('EXISTS', () => { - describe('transformArguments', () => { + describe('parseCommand', () => { it('string', () => { assert.deepEqual( - EXISTS.transformArguments('key'), + parseArgs(EXISTS, 'key'), ['EXISTS', 'key'] ); }); it('array', () => { assert.deepEqual( - EXISTS.transformArguments(['1', '2']), + parseArgs(EXISTS, ['1', '2']), ['EXISTS', '1', '2'] ); }); diff --git a/packages/client/lib/commands/EXISTS.ts b/packages/client/lib/commands/EXISTS.ts index a077943b8d..8ebb28269f 100644 --- a/packages/client/lib/commands/EXISTS.ts +++ b/packages/client/lib/commands/EXISTS.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArguments(['EXISTS'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('EXISTS'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EXPIRE.spec.ts b/packages/client/lib/commands/EXPIRE.spec.ts index 817e37cca4..f3d197b5c6 100644 --- a/packages/client/lib/commands/EXPIRE.spec.ts +++ b/packages/client/lib/commands/EXPIRE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EXPIRE from './EXPIRE'; +import { parseArgs } from './generic-transformers'; describe('EXPIRE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - EXPIRE.transformArguments('key', 1), + parseArgs(EXPIRE, 'key', 1), ['EXPIRE', 'key', '1'] ); }); it('with set option', () => { assert.deepEqual( - EXPIRE.transformArguments('key', 1, 'NX'), + parseArgs(EXPIRE, 'key', 1, 'NX'), ['EXPIRE', 'key', '1', 'NX'] ); }); diff --git a/packages/client/lib/commands/EXPIRE.ts b/packages/client/lib/commands/EXPIRE.ts index 3e57769bd6..1e73b62949 100644 --- a/packages/client/lib/commands/EXPIRE.ts +++ b/packages/client/lib/commands/EXPIRE.ts @@ -1,20 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, seconds: number, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['EXPIRE', key, seconds.toString()]; - + parser.push('EXPIRE'); + parser.pushKey(key); + parser.push(seconds.toString()); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EXPIREAT.spec.ts b/packages/client/lib/commands/EXPIREAT.spec.ts index 31efdcea39..1949fb051b 100644 --- a/packages/client/lib/commands/EXPIREAT.spec.ts +++ b/packages/client/lib/commands/EXPIREAT.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EXPIREAT from './EXPIREAT'; +import { parseArgs } from './generic-transformers'; describe('EXPIREAT', () => { describe('transformArguments', () => { it('number', () => { assert.deepEqual( - EXPIREAT.transformArguments('key', 1), + parseArgs(EXPIREAT, 'key', 1), ['EXPIREAT', 'key', '1'] ); }); @@ -14,14 +15,14 @@ describe('EXPIREAT', () => { it('date', () => { const d = new Date(); assert.deepEqual( - EXPIREAT.transformArguments('key', d), + parseArgs(EXPIREAT, 'key', d), ['EXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString()] ); }); it('with set option', () => { assert.deepEqual( - EXPIREAT.transformArguments('key', 1, 'GT'), + parseArgs(EXPIREAT, 'key', 1, 'GT'), ['EXPIREAT', 'key', '1', 'GT'] ); }); diff --git a/packages/client/lib/commands/EXPIREAT.ts b/packages/client/lib/commands/EXPIREAT.ts index 9a959a87f9..5bcb94ea32 100644 --- a/packages/client/lib/commands/EXPIREAT.ts +++ b/packages/client/lib/commands/EXPIREAT.ts @@ -1,21 +1,21 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { transformEXAT } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, timestamp: number | Date, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['EXPIREAT', key, transformEXAT(timestamp)]; - + parser.push('EXPIREAT'); + parser.pushKey(key); + parser.push(transformEXAT(timestamp)); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/EXPIRETIME.spec.ts b/packages/client/lib/commands/EXPIRETIME.spec.ts index 3c202d2427..f2c8d3d452 100644 --- a/packages/client/lib/commands/EXPIRETIME.spec.ts +++ b/packages/client/lib/commands/EXPIRETIME.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EXPIRETIME from './EXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('EXPIRETIME', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - EXPIRETIME.transformArguments('key'), + parseArgs(EXPIRETIME, 'key'), ['EXPIRETIME', 'key'] ); }); diff --git a/packages/client/lib/commands/EXPIRETIME.ts b/packages/client/lib/commands/EXPIRETIME.ts index d6ac35aeb3..2bb97fb737 100644 --- a/packages/client/lib/commands/EXPIRETIME.ts +++ b/packages/client/lib/commands/EXPIRETIME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['EXPIRETIME', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('EXPIRETIME'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FAILOVER.spec.ts b/packages/client/lib/commands/FAILOVER.spec.ts index 96602caff9..b23c3516f0 100644 --- a/packages/client/lib/commands/FAILOVER.spec.ts +++ b/packages/client/lib/commands/FAILOVER.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import FAILOVER from './FAILOVER'; +import { parseArgs } from './generic-transformers'; describe('FAILOVER', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FAILOVER.transformArguments(), + parseArgs(FAILOVER), ['FAILOVER'] ); }); @@ -13,7 +14,7 @@ describe('FAILOVER', () => { describe('with TO', () => { it('simple', () => { assert.deepEqual( - FAILOVER.transformArguments({ + parseArgs(FAILOVER, { TO: { host: 'host', port: 6379 @@ -25,7 +26,7 @@ describe('FAILOVER', () => { it('with FORCE', () => { assert.deepEqual( - FAILOVER.transformArguments({ + parseArgs(FAILOVER, { TO: { host: 'host', port: 6379, @@ -39,7 +40,7 @@ describe('FAILOVER', () => { it('with ABORT', () => { assert.deepEqual( - FAILOVER.transformArguments({ + parseArgs(FAILOVER, { ABORT: true }), ['FAILOVER', 'ABORT'] @@ -48,7 +49,7 @@ describe('FAILOVER', () => { it('with TIMEOUT', () => { assert.deepEqual( - FAILOVER.transformArguments({ + parseArgs(FAILOVER, { TIMEOUT: 1 }), ['FAILOVER', 'TIMEOUT', '1'] @@ -57,7 +58,7 @@ describe('FAILOVER', () => { it('with TO, ABORT, TIMEOUT', () => { assert.deepEqual( - FAILOVER.transformArguments({ + parseArgs(FAILOVER, { TO: { host: 'host', port: 6379 diff --git a/packages/client/lib/commands/FAILOVER.ts b/packages/client/lib/commands/FAILOVER.ts index 0c1e710d32..1e98b983f9 100644 --- a/packages/client/lib/commands/FAILOVER.ts +++ b/packages/client/lib/commands/FAILOVER.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; interface FailoverOptions { @@ -11,26 +12,24 @@ interface FailoverOptions { } export default { - transformArguments(options?: FailoverOptions) { - const args = ['FAILOVER']; + parseCommand(parser: CommandParser, options?: FailoverOptions) { + parser.push('FAILOVER'); if (options?.TO) { - args.push('TO', options.TO.host, options.TO.port.toString()); + parser.push('TO', options.TO.host, options.TO.port.toString()); if (options.TO.FORCE) { - args.push('FORCE'); + parser.push('FORCE'); } } if (options?.ABORT) { - args.push('ABORT'); + parser.push('ABORT'); } if (options?.TIMEOUT) { - args.push('TIMEOUT', options.TIMEOUT.toString()); + parser.push('TIMEOUT', options.TIMEOUT.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FCALL.spec.ts b/packages/client/lib/commands/FCALL.spec.ts index 286f2a371b..6c3a65c144 100644 --- a/packages/client/lib/commands/FCALL.spec.ts +++ b/packages/client/lib/commands/FCALL.spec.ts @@ -2,13 +2,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import { MATH_FUNCTION, loadMathFunction } from './FUNCTION_LOAD.spec'; import FCALL from './FCALL'; +import { parseArgs } from './generic-transformers'; describe('FCALL', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FCALL.transformArguments('function', { + parseArgs(FCALL, 'function', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/FCALL.ts b/packages/client/lib/commands/FCALL.ts index ba371a81b1..622060f693 100644 --- a/packages/client/lib/commands/FCALL.ts +++ b/packages/client/lib/commands/FCALL.ts @@ -1,9 +1,11 @@ import { Command } from '../RESP/types'; -import EVAL, { transformEvalArguments } from './EVAL'; +import EVAL, { parseEvalArguments } from './EVAL'; export default { - FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, IS_READ_ONLY: false, - transformArguments: transformEvalArguments.bind(undefined, 'FCALL'), + parseCommand(...args: Parameters) { + args[0].push('FCALL'); + parseEvalArguments(...args); + }, transformReply: EVAL.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FCALL_RO.spec.ts b/packages/client/lib/commands/FCALL_RO.spec.ts index 57edcebebe..447e00072b 100644 --- a/packages/client/lib/commands/FCALL_RO.spec.ts +++ b/packages/client/lib/commands/FCALL_RO.spec.ts @@ -2,13 +2,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import { MATH_FUNCTION, loadMathFunction } from './FUNCTION_LOAD.spec'; import FCALL_RO from './FCALL_RO'; +import { parseArgs } from './generic-transformers'; describe('FCALL_RO', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FCALL_RO.transformArguments('function', { + parseArgs(FCALL_RO, 'function', { keys: ['key'], arguments: ['argument'] }), diff --git a/packages/client/lib/commands/FCALL_RO.ts b/packages/client/lib/commands/FCALL_RO.ts index ec002a79f8..95effb0e69 100644 --- a/packages/client/lib/commands/FCALL_RO.ts +++ b/packages/client/lib/commands/FCALL_RO.ts @@ -1,9 +1,11 @@ import { Command } from '../RESP/types'; -import EVAL, { transformEvalArguments } from './EVAL'; +import EVAL, { parseEvalArguments } from './EVAL'; export default { - FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, IS_READ_ONLY: false, - transformArguments: transformEvalArguments.bind(undefined, 'FCALL_RO'), + parseCommand(...args: Parameters) { + args[0].push('FCALL_RO'); + parseEvalArguments(...args); + }, transformReply: EVAL.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FLUSHALL.spec.ts b/packages/client/lib/commands/FLUSHALL.spec.ts index 63ad38dd7d..86daff1973 100644 --- a/packages/client/lib/commands/FLUSHALL.spec.ts +++ b/packages/client/lib/commands/FLUSHALL.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FLUSHALL, { REDIS_FLUSH_MODES } from './FLUSHALL'; +import { parseArgs } from './generic-transformers'; describe('FLUSHALL', () => { describe('transformArguments', () => { it('default', () => { assert.deepEqual( - FLUSHALL.transformArguments(), + parseArgs(FLUSHALL), ['FLUSHALL'] ); }); it('ASYNC', () => { assert.deepEqual( - FLUSHALL.transformArguments(REDIS_FLUSH_MODES.ASYNC), + parseArgs(FLUSHALL,REDIS_FLUSH_MODES.ASYNC), ['FLUSHALL', 'ASYNC'] ); }); it('SYNC', () => { assert.deepEqual( - FLUSHALL.transformArguments(REDIS_FLUSH_MODES.SYNC), + parseArgs(FLUSHALL, REDIS_FLUSH_MODES.SYNC), ['FLUSHALL', 'SYNC'] ); }); diff --git a/packages/client/lib/commands/FLUSHALL.ts b/packages/client/lib/commands/FLUSHALL.ts index 5e6484a991..c39535e886 100644 --- a/packages/client/lib/commands/FLUSHALL.ts +++ b/packages/client/lib/commands/FLUSHALL.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export const REDIS_FLUSH_MODES = { @@ -8,16 +9,13 @@ export const REDIS_FLUSH_MODES = { export type RedisFlushMode = typeof REDIS_FLUSH_MODES[keyof typeof REDIS_FLUSH_MODES]; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(mode?: RedisFlushMode) { - const args = ['FLUSHALL']; - + parseCommand(parser: CommandParser, mode?: RedisFlushMode) { + parser.push('FLUSHALL'); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FLUSHDB.spec.ts b/packages/client/lib/commands/FLUSHDB.spec.ts index ad09ecfc94..795df637cb 100644 --- a/packages/client/lib/commands/FLUSHDB.spec.ts +++ b/packages/client/lib/commands/FLUSHDB.spec.ts @@ -2,26 +2,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FLUSHDB from './FLUSHDB'; import { REDIS_FLUSH_MODES } from './FLUSHALL'; +import { parseArgs } from './generic-transformers'; describe('FLUSHDB', () => { describe('transformArguments', () => { it('default', () => { assert.deepEqual( - FLUSHDB.transformArguments(), + parseArgs(FLUSHDB), ['FLUSHDB'] ); }); it('ASYNC', () => { assert.deepEqual( - FLUSHDB.transformArguments(REDIS_FLUSH_MODES.ASYNC), + parseArgs(FLUSHDB, REDIS_FLUSH_MODES.ASYNC), ['FLUSHDB', 'ASYNC'] ); }); it('SYNC', () => { assert.deepEqual( - FLUSHDB.transformArguments(REDIS_FLUSH_MODES.SYNC), + parseArgs(FLUSHDB, REDIS_FLUSH_MODES.SYNC), ['FLUSHDB', 'SYNC'] ); }); diff --git a/packages/client/lib/commands/FLUSHDB.ts b/packages/client/lib/commands/FLUSHDB.ts index 75c7a66f19..5639f69a61 100644 --- a/packages/client/lib/commands/FLUSHDB.ts +++ b/packages/client/lib/commands/FLUSHDB.ts @@ -1,17 +1,15 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; import { RedisFlushMode } from './FLUSHALL'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(mode?: RedisFlushMode) { - const args = ['FLUSHDB']; - + parseCommand(parser: CommandParser, mode?: RedisFlushMode) { + parser.push('FLUSHDB'); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_DELETE.spec.ts b/packages/client/lib/commands/FUNCTION_DELETE.spec.ts index 1172e84b95..b33ea25916 100644 --- a/packages/client/lib/commands/FUNCTION_DELETE.spec.ts +++ b/packages/client/lib/commands/FUNCTION_DELETE.spec.ts @@ -2,13 +2,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_DELETE from './FUNCTION_DELETE'; import { MATH_FUNCTION, loadMathFunction } from './FUNCTION_LOAD.spec'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION DELETE', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FUNCTION_DELETE.transformArguments('library'), + parseArgs(FUNCTION_DELETE, 'library'), ['FUNCTION', 'DELETE', 'library'] ); }); diff --git a/packages/client/lib/commands/FUNCTION_DELETE.ts b/packages/client/lib/commands/FUNCTION_DELETE.ts index 1061cded17..dbfb044928 100644 --- a/packages/client/lib/commands/FUNCTION_DELETE.ts +++ b/packages/client/lib/commands/FUNCTION_DELETE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(library: RedisArgument) { - return ['FUNCTION', 'DELETE', library]; + parseCommand(parser: CommandParser, library: RedisArgument) { + parser.push('FUNCTION', 'DELETE', library); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_DUMP.spec.ts b/packages/client/lib/commands/FUNCTION_DUMP.spec.ts index 4d4e885e4f..bbd6302bb6 100644 --- a/packages/client/lib/commands/FUNCTION_DUMP.spec.ts +++ b/packages/client/lib/commands/FUNCTION_DUMP.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_DUMP from './FUNCTION_DUMP'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION DUMP', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FUNCTION_DUMP.transformArguments(), + parseArgs(FUNCTION_DUMP), ['FUNCTION', 'DUMP'] ); }); diff --git a/packages/client/lib/commands/FUNCTION_DUMP.ts b/packages/client/lib/commands/FUNCTION_DUMP.ts index 8f6ff047fa..2d0dbdd445 100644 --- a/packages/client/lib/commands/FUNCTION_DUMP.ts +++ b/packages/client/lib/commands/FUNCTION_DUMP.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['FUNCTION', 'DUMP']; + parseCommand(parser: CommandParser) { + parser.push('FUNCTION', 'DUMP') }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_FLUSH.spec.ts b/packages/client/lib/commands/FUNCTION_FLUSH.spec.ts index 5601784ed6..4fe90bdb60 100644 --- a/packages/client/lib/commands/FUNCTION_FLUSH.spec.ts +++ b/packages/client/lib/commands/FUNCTION_FLUSH.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_FLUSH from './FUNCTION_FLUSH'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION FLUSH', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('FUNCTION FLUSH', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FUNCTION_FLUSH.transformArguments(), + parseArgs(FUNCTION_FLUSH), ['FUNCTION', 'FLUSH'] ); }); it('with mode', () => { assert.deepEqual( - FUNCTION_FLUSH.transformArguments('SYNC'), + parseArgs(FUNCTION_FLUSH, 'SYNC'), ['FUNCTION', 'FLUSH', 'SYNC'] ); }); diff --git a/packages/client/lib/commands/FUNCTION_FLUSH.ts b/packages/client/lib/commands/FUNCTION_FLUSH.ts index 844d3586d9..4ca59e4464 100644 --- a/packages/client/lib/commands/FUNCTION_FLUSH.ts +++ b/packages/client/lib/commands/FUNCTION_FLUSH.ts @@ -1,17 +1,16 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; import { RedisFlushMode } from './FLUSHALL'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(mode?: RedisFlushMode) { - const args = ['FUNCTION', 'FLUSH']; - + parseCommand(parser: CommandParser, mode?: RedisFlushMode) { + parser.push('FUNCTION', 'FLUSH'); + if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_KILL.spec.ts b/packages/client/lib/commands/FUNCTION_KILL.spec.ts index be231e4118..c4dbd124d3 100644 --- a/packages/client/lib/commands/FUNCTION_KILL.spec.ts +++ b/packages/client/lib/commands/FUNCTION_KILL.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils from '../test-utils'; import FUNCTION_KILL from './FUNCTION_KILL'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION KILL', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FUNCTION_KILL.transformArguments(), + parseArgs(FUNCTION_KILL), ['FUNCTION', 'KILL'] ); }); diff --git a/packages/client/lib/commands/FUNCTION_KILL.ts b/packages/client/lib/commands/FUNCTION_KILL.ts index f452b0b80d..8b5351e93a 100644 --- a/packages/client/lib/commands/FUNCTION_KILL.ts +++ b/packages/client/lib/commands/FUNCTION_KILL.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['FUNCTION', 'KILL']; + parseCommand(parser: CommandParser) { + parser.push('FUNCTION', 'KILL'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_LIST.spec.ts b/packages/client/lib/commands/FUNCTION_LIST.spec.ts index e269d3150b..6d9b28acf9 100644 --- a/packages/client/lib/commands/FUNCTION_LIST.spec.ts +++ b/packages/client/lib/commands/FUNCTION_LIST.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_LIST from './FUNCTION_LIST'; import { MATH_FUNCTION, loadMathFunction } from './FUNCTION_LOAD.spec'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION LIST', () => { testUtils.isVersionGreaterThanHook([7]); @@ -9,14 +10,14 @@ describe('FUNCTION LIST', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FUNCTION_LIST.transformArguments(), + parseArgs(FUNCTION_LIST), ['FUNCTION', 'LIST'] ); }); it('with LIBRARYNAME', () => { assert.deepEqual( - FUNCTION_LIST.transformArguments({ + parseArgs(FUNCTION_LIST, { LIBRARYNAME: 'patter*' }), ['FUNCTION', 'LIST', 'LIBRARYNAME', 'patter*'] diff --git a/packages/client/lib/commands/FUNCTION_LIST.ts b/packages/client/lib/commands/FUNCTION_LIST.ts index 07c1ff2a00..82e3697ead 100644 --- a/packages/client/lib/commands/FUNCTION_LIST.ts +++ b/packages/client/lib/commands/FUNCTION_LIST.ts @@ -1,4 +1,5 @@ -import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NullReply, SetReply, UnwrapReply, Resp2Reply, CommandArguments, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NullReply, SetReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; export interface FunctionListOptions { LIBRARYNAME?: RedisArgument; @@ -17,16 +18,14 @@ export type FunctionListReplyItem = [ export type FunctionListReply = ArrayReply>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(options?: FunctionListOptions) { - const args: CommandArguments = ['FUNCTION', 'LIST']; + parseCommand(parser: CommandParser, options?: FunctionListOptions) { + parser.push('FUNCTION', 'LIST'); if (options?.LIBRARYNAME) { - args.push('LIBRARYNAME', options.LIBRARYNAME); + parser.push('LIBRARYNAME', options.LIBRARYNAME); } - - return args; }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.spec.ts b/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.spec.ts index 8ff4058246..f44db9ba03 100644 --- a/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.spec.ts +++ b/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_LIST_WITHCODE from './FUNCTION_LIST_WITHCODE'; import { MATH_FUNCTION, loadMathFunction } from './FUNCTION_LOAD.spec'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION LIST WITHCODE', () => { testUtils.isVersionGreaterThanHook([7]); @@ -9,14 +10,14 @@ describe('FUNCTION LIST WITHCODE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FUNCTION_LIST_WITHCODE.transformArguments(), + parseArgs(FUNCTION_LIST_WITHCODE), ['FUNCTION', 'LIST', 'WITHCODE'] ); }); it('with LIBRARYNAME', () => { assert.deepEqual( - FUNCTION_LIST_WITHCODE.transformArguments({ + parseArgs(FUNCTION_LIST_WITHCODE, { LIBRARYNAME: 'patter*' }), ['FUNCTION', 'LIST', 'LIBRARYNAME', 'patter*', 'WITHCODE'] diff --git a/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.ts b/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.ts index 47a02a3da8..208bc5fd30 100644 --- a/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.ts +++ b/packages/client/lib/commands/FUNCTION_LIST_WITHCODE.ts @@ -7,12 +7,11 @@ export type FunctionListWithCodeReply = ArrayReply>; export default { - FIRST_KEY_INDEX: FUNCTION_LIST.FIRST_KEY_INDEX, + NOT_KEYED_COMMAND: FUNCTION_LIST.NOT_KEYED_COMMAND, IS_READ_ONLY: FUNCTION_LIST.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = FUNCTION_LIST.transformArguments(...args); - redisArgs.push('WITHCODE'); - return redisArgs; + parseCommand(...args: Parameters) { + FUNCTION_LIST.parseCommand(...args); + args[0].push('WITHCODE'); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/FUNCTION_LOAD.spec.ts b/packages/client/lib/commands/FUNCTION_LOAD.spec.ts index fe896bdf8c..c0a511bffc 100644 --- a/packages/client/lib/commands/FUNCTION_LOAD.spec.ts +++ b/packages/client/lib/commands/FUNCTION_LOAD.spec.ts @@ -3,6 +3,8 @@ import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_LOAD from './FUNCTION_LOAD'; import { RedisClientType } from '../client'; import { NumberReply, RedisFunctions, RedisModules, RedisScripts, RespVersions } from '../RESP/types'; +import { parseArgs } from './generic-transformers'; +import { CommandParser } from '../client/parser'; @@ -25,8 +27,8 @@ export const MATH_FUNCTION = { IS_READ_ONLY: true, NUMBER_OF_KEYS: 1, FIRST_KEY_INDEX: 0, - transformArguments(key: string) { - return [key]; + parseCommand(parser: CommandParser, key: string) { + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } @@ -53,14 +55,14 @@ describe('FUNCTION LOAD', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FUNCTION_LOAD.transformArguments('code'), + parseArgs(FUNCTION_LOAD, 'code'), ['FUNCTION', 'LOAD', 'code'] ); }); it('with REPLACE', () => { assert.deepEqual( - FUNCTION_LOAD.transformArguments('code', { + parseArgs(FUNCTION_LOAD, 'code', { REPLACE: true }), ['FUNCTION', 'LOAD', 'REPLACE', 'code'] diff --git a/packages/client/lib/commands/FUNCTION_LOAD.ts b/packages/client/lib/commands/FUNCTION_LOAD.ts index 32b030909a..40b8ea8c0f 100644 --- a/packages/client/lib/commands/FUNCTION_LOAD.ts +++ b/packages/client/lib/commands/FUNCTION_LOAD.ts @@ -1,22 +1,21 @@ -import { RedisArgument, CommandArguments, BlobStringReply, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export interface FunctionLoadOptions { REPLACE?: boolean; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(code: RedisArgument, options?: FunctionLoadOptions) { - const args: CommandArguments = ['FUNCTION', 'LOAD']; + parseCommand(parser: CommandParser, code: RedisArgument, options?: FunctionLoadOptions) { + parser.push('FUNCTION', 'LOAD'); if (options?.REPLACE) { - args.push('REPLACE'); + parser.push('REPLACE'); } - args.push(code); - - return args; + parser.push(code); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_RESTORE.spec.ts b/packages/client/lib/commands/FUNCTION_RESTORE.spec.ts index 465e99b610..72d7d1d620 100644 --- a/packages/client/lib/commands/FUNCTION_RESTORE.spec.ts +++ b/packages/client/lib/commands/FUNCTION_RESTORE.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_RESTORE from './FUNCTION_RESTORE'; import { RESP_TYPES } from '../RESP/decoder'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION RESTORE', () => { testUtils.isVersionGreaterThanHook([7]); @@ -9,14 +10,14 @@ describe('FUNCTION RESTORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - FUNCTION_RESTORE.transformArguments('dump'), + parseArgs(FUNCTION_RESTORE, 'dump'), ['FUNCTION', 'RESTORE', 'dump'] ); }); it('with mode', () => { assert.deepEqual( - FUNCTION_RESTORE.transformArguments('dump', { + parseArgs(FUNCTION_RESTORE, 'dump', { mode: 'APPEND' }), ['FUNCTION', 'RESTORE', 'dump', 'APPEND'] diff --git a/packages/client/lib/commands/FUNCTION_RESTORE.ts b/packages/client/lib/commands/FUNCTION_RESTORE.ts index 8c87553056..944813f25e 100644 --- a/packages/client/lib/commands/FUNCTION_RESTORE.ts +++ b/packages/client/lib/commands/FUNCTION_RESTORE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command, RedisArgument } from '../RESP/types'; export interface FunctionRestoreOptions { @@ -5,16 +6,14 @@ export interface FunctionRestoreOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(dump: RedisArgument, options?: FunctionRestoreOptions) { - const args = ['FUNCTION', 'RESTORE', dump]; + parseCommand(parser: CommandParser, dump: RedisArgument, options?: FunctionRestoreOptions) { + parser.push('FUNCTION', 'RESTORE', dump); if (options?.mode) { - args.push(options.mode); + parser.push(options.mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/FUNCTION_STATS.spec.ts b/packages/client/lib/commands/FUNCTION_STATS.spec.ts index b48b012614..a3c5e00fe7 100644 --- a/packages/client/lib/commands/FUNCTION_STATS.spec.ts +++ b/packages/client/lib/commands/FUNCTION_STATS.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FUNCTION_STATS from './FUNCTION_STATS'; +import { parseArgs } from './generic-transformers'; describe('FUNCTION STATS', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - FUNCTION_STATS.transformArguments(), + parseArgs(FUNCTION_STATS), ['FUNCTION', 'STATS'] ); }); diff --git a/packages/client/lib/commands/FUNCTION_STATS.ts b/packages/client/lib/commands/FUNCTION_STATS.ts index 138d1fb82d..908be5476e 100644 --- a/packages/client/lib/commands/FUNCTION_STATS.ts +++ b/packages/client/lib/commands/FUNCTION_STATS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { Command, TuplesToMapReply, BlobStringReply, NullReply, NumberReply, MapReply, Resp2Reply, UnwrapReply } from '../RESP/types'; import { isNullReply } from './generic-transformers'; @@ -20,10 +21,10 @@ type FunctionStatsReply = TuplesToMapReply<[ ]>; export default { + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - FIRST_KEY_INDEX: undefined, - transformArguments() { - return ['FUNCTION', 'STATS']; + parseCommand(parser: CommandParser) { + parser.push('FUNCTION', 'STATS'); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/GEOADD.spec.ts b/packages/client/lib/commands/GEOADD.spec.ts index 14195ed289..d947141a31 100644 --- a/packages/client/lib/commands/GEOADD.spec.ts +++ b/packages/client/lib/commands/GEOADD.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOADD from './GEOADD'; +import { parseArgs } from './generic-transformers'; describe('GEOADD', () => { describe('transformArguments', () => { it('one member', () => { assert.deepEqual( - GEOADD.transformArguments('key', { + parseArgs(GEOADD, 'key', { member: 'member', longitude: 1, latitude: 2 @@ -17,7 +18,7 @@ describe('GEOADD', () => { it('multiple members', () => { assert.deepEqual( - GEOADD.transformArguments('key', [{ + parseArgs(GEOADD, 'key', [{ longitude: 1, latitude: 2, member: '3', @@ -32,7 +33,7 @@ describe('GEOADD', () => { it('with condition', () => { assert.deepEqual( - GEOADD.transformArguments('key', { + parseArgs(GEOADD, 'key', { longitude: 1, latitude: 2, member: 'member' @@ -45,7 +46,7 @@ describe('GEOADD', () => { it('with NX (backwards compatibility)', () => { assert.deepEqual( - GEOADD.transformArguments('key', { + parseArgs(GEOADD, 'key', { longitude: 1, latitude: 2, member: 'member' @@ -58,7 +59,7 @@ describe('GEOADD', () => { it('with CH', () => { assert.deepEqual( - GEOADD.transformArguments('key', { + parseArgs(GEOADD, 'key', { longitude: 1, latitude: 2, member: 'member' @@ -71,7 +72,7 @@ describe('GEOADD', () => { it('with condition, CH', () => { assert.deepEqual( - GEOADD.transformArguments('key', { + parseArgs(GEOADD, 'key', { longitude: 1, latitude: 2, member: 'member' diff --git a/packages/client/lib/commands/GEOADD.ts b/packages/client/lib/commands/GEOADD.ts index f89f6b80e8..31bf457e15 100644 --- a/packages/client/lib/commands/GEOADD.ts +++ b/packages/client/lib/commands/GEOADD.ts @@ -1,4 +1,5 @@ -import { RedisArgument, CommandArguments, NumberReply, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { GeoCoordinates } from './GEOSEARCH'; export interface GeoMember extends GeoCoordinates { @@ -19,45 +20,45 @@ export interface GeoAddOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, toAdd: GeoMember | Array, options?: GeoAddOptions ) { - const args = ['GEOADD', key]; + parser.push('GEOADD') + parser.pushKey(key); if (options?.condition) { - args.push(options.condition); + parser.push(options.condition); } else if (options?.NX) { - args.push('NX'); + parser.push('NX'); } else if (options?.XX) { - args.push('XX'); + parser.push('XX'); } if (options?.CH) { - args.push('CH'); + parser.push('CH'); } if (Array.isArray(toAdd)) { for (const member of toAdd) { - pushMember(args, member); + pushMember(parser, member); } } else { - pushMember(args, toAdd); + pushMember(parser, toAdd); } - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; function pushMember( - args: CommandArguments, + parser: CommandParser, { longitude, latitude, member }: GeoMember ) { - args.push( + parser.push( longitude.toString(), latitude.toString(), member diff --git a/packages/client/lib/commands/GEODIST.spec.ts b/packages/client/lib/commands/GEODIST.spec.ts index eb5a1ef801..a23df405d1 100644 --- a/packages/client/lib/commands/GEODIST.spec.ts +++ b/packages/client/lib/commands/GEODIST.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEODIST from './GEODIST'; +import { parseArgs } from './generic-transformers'; describe('GEODIST', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - GEODIST.transformArguments('key', '1', '2'), + parseArgs(GEODIST, 'key', '1', '2'), ['GEODIST', 'key', '1', '2'] ); }); it('with unit', () => { assert.deepEqual( - GEODIST.transformArguments('key', '1', '2', 'm'), + parseArgs(GEODIST, 'key', '1', '2', 'm'), ['GEODIST', 'key', '1', '2', 'm'] ); }); diff --git a/packages/client/lib/commands/GEODIST.ts b/packages/client/lib/commands/GEODIST.ts index 3e684d6757..ba4d3080a7 100644 --- a/packages/client/lib/commands/GEODIST.ts +++ b/packages/client/lib/commands/GEODIST.ts @@ -1,22 +1,23 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; import { GeoUnits } from './GEOSEARCH'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand(parser: CommandParser, key: RedisArgument, member1: RedisArgument, member2: RedisArgument, unit?: GeoUnits ) { - const args = ['GEODIST', key, member1, member2]; + parser.push('GEODIST'); + parser.pushKey(key); + parser.push(member1, member2); if (unit) { - args.push(unit); + parser.push(unit); } - - return args; }, transformReply(reply: BlobStringReply | NullReply) { return reply === null ? null : Number(reply); diff --git a/packages/client/lib/commands/GEOHASH.spec.ts b/packages/client/lib/commands/GEOHASH.spec.ts index 8efe55d89b..ad26dff843 100644 --- a/packages/client/lib/commands/GEOHASH.spec.ts +++ b/packages/client/lib/commands/GEOHASH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOHASH from './GEOHASH'; +import { parseArgs } from './generic-transformers'; describe('GEOHASH', () => { describe('transformArguments', () => { it('single member', () => { assert.deepEqual( - GEOHASH.transformArguments('key', 'member'), + parseArgs(GEOHASH, 'key', 'member'), ['GEOHASH', 'key', 'member'] ); }); it('multiple members', () => { assert.deepEqual( - GEOHASH.transformArguments('key', ['1', '2']), + parseArgs(GEOHASH, 'key', ['1', '2']), ['GEOHASH', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/GEOHASH.ts b/packages/client/lib/commands/GEOHASH.ts index d8d2732e51..c3265d1315 100644 --- a/packages/client/lib/commands/GEOHASH.ts +++ b/packages/client/lib/commands/GEOHASH.ts @@ -1,14 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - member: RedisVariadicArgument - ) { - return pushVariadicArguments(['GEOHASH', key], member); + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisVariadicArgument) { + parser.push('GEOHASH'); + parser.pushKey(key); + parser.pushVariadic(member); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEOPOS.spec.ts b/packages/client/lib/commands/GEOPOS.spec.ts index 20ad5c5c94..247dd91d22 100644 --- a/packages/client/lib/commands/GEOPOS.spec.ts +++ b/packages/client/lib/commands/GEOPOS.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOPOS from './GEOPOS'; +import { parseArgs } from './generic-transformers'; describe('GEOPOS', () => { describe('transformArguments', () => { it('single member', () => { assert.deepEqual( - GEOPOS.transformArguments('key', 'member'), + parseArgs(GEOPOS, 'key', 'member'), ['GEOPOS', 'key', 'member'] ); }); it('multiple members', () => { assert.deepEqual( - GEOPOS.transformArguments('key', ['1', '2']), + parseArgs(GEOPOS, 'key', ['1', '2']), ['GEOPOS', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/GEOPOS.ts b/packages/client/lib/commands/GEOPOS.ts index 30273c64c1..6bdbb65ac4 100644 --- a/packages/client/lib/commands/GEOPOS.ts +++ b/packages/client/lib/commands/GEOPOS.ts @@ -1,14 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, NullReply, UnwrapReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - member: RedisVariadicArgument - ) { - return pushVariadicArguments(['GEOPOS', key], member); + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisVariadicArgument) { + parser.push('GEOPOS'); + parser.pushKey(key); + parser.pushVariadic(member); }, transformReply(reply: UnwrapReply | NullReply>>) { return reply.map(item => { diff --git a/packages/client/lib/commands/GEORADIUS.spec.ts b/packages/client/lib/commands/GEORADIUS.spec.ts index 533e48f689..3c33395c5f 100644 --- a/packages/client/lib/commands/GEORADIUS.spec.ts +++ b/packages/client/lib/commands/GEORADIUS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUS from './GEORADIUS'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUS', () => { it('transformArguments', () => { assert.deepEqual( - GEORADIUS.transformArguments('key', { + parseArgs(GEORADIUS, 'key', { longitude: 1, latitude: 2 }, 3, 'm'), diff --git a/packages/client/lib/commands/GEORADIUS.ts b/packages/client/lib/commands/GEORADIUS.ts index e777432f09..5e8d880ab5 100644 --- a/packages/client/lib/commands/GEORADIUS.ts +++ b/packages/client/lib/commands/GEORADIUS.ts @@ -1,32 +1,27 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { GeoCoordinates, GeoUnits, GeoSearchOptions, pushGeoSearchOptions } from './GEOSEARCH'; +import { GeoCoordinates, GeoUnits, GeoSearchOptions, parseGeoSearchOptions } from './GEOSEARCH'; -export function transformGeoRadiusArguments( - command: RedisArgument, +export function parseGeoRadiusArguments( + parser: CommandParser, key: RedisArgument, from: GeoCoordinates, radius: number, unit: GeoUnits, options?: GeoSearchOptions ) { - const args = [ - command, - key, - from.longitude.toString(), - from.latitude.toString(), - radius.toString(), - unit - ]; + parser.pushKey(key); + parser.push(from.longitude.toString(), from.latitude.toString(), radius.toString(), unit); - pushGeoSearchOptions(args, options); - - return args; + parseGeoSearchOptions(parser, options) } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments: transformGeoRadiusArguments.bind(undefined, 'GEORADIUS'), + parseCommand(...args: Parameters) { + args[0].push('GEORADIUS'); + return parseGeoRadiusArguments(...args); + }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER.spec.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER.spec.ts index 57349a79ac..c81c3d7581 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER.spec.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUSBYMEMBER', () => { it('transformArguments', () => { assert.deepEqual( - GEORADIUSBYMEMBER.transformArguments('key', 'member', 3, 'm'), + parseArgs(GEORADIUSBYMEMBER, 'key', 'member', 3, 'm'), ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm'] ); }); diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER.ts index 13b52a3063..be4ca54650 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER.ts @@ -1,30 +1,33 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { GeoUnits, GeoSearchOptions, pushGeoSearchOptions } from './GEOSEARCH'; +import { GeoUnits, GeoSearchOptions, parseGeoSearchOptions } from './GEOSEARCH'; -export function transformGeoRadiusByMemberArguments( - command: RedisArgument, +export function parseGeoRadiusByMemberArguments( + parser: CommandParser, key: RedisArgument, from: RedisArgument, radius: number, unit: GeoUnits, options?: GeoSearchOptions ) { - const args = [ - command, - key, - from, - radius.toString(), - unit - ]; + parser.pushKey(key); + parser.push(from, radius.toString(), unit); - pushGeoSearchOptions(args, options); - - return args; + parseGeoSearchOptions(parser, options); } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments: transformGeoRadiusByMemberArguments.bind(undefined, 'GEORADIUSBYMEMBER'), + parseCommand( + parser: CommandParser, + key: RedisArgument, + from: RedisArgument, + radius: number, + unit: GeoUnits, + options?: GeoSearchOptions + ) { + parser.push('GEORADIUSBYMEMBER'); + parseGeoRadiusByMemberArguments(parser, key, from, radius, unit, options); + }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.spec.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.spec.ts index abf1001397..bd4aa86dec 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.spec.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUSBYMEMBER_RO from './GEORADIUSBYMEMBER_RO'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUSBYMEMBER_RO', () => { it('transformArguments', () => { assert.deepEqual( - GEORADIUSBYMEMBER_RO.transformArguments('key', 'member', 3, 'm'), + parseArgs(GEORADIUSBYMEMBER_RO, 'key', 'member', 3, 'm'), ['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm'] ); }); diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.ts index 7f85ed15df..335eea0813 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO.ts @@ -1,9 +1,13 @@ import { Command } from '../RESP/types'; -import GEORADIUSBYMEMBER, { transformGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER'; +import GEORADIUSBYMEMBER, { parseGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER'; export default { - FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments: transformGeoRadiusByMemberArguments.bind(undefined, 'GEORADIUSBYMEMBER_RO'), + parseCommand(...args: Parameters) { + const parser = args[0]; + parser.push('GEORADIUSBYMEMBER_RO'); + parseGeoRadiusByMemberArguments(...args); + }, transformReply: GEORADIUSBYMEMBER.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.spec.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.spec.ts index bcf9126636..52b31b0359 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.spec.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.spec.ts @@ -3,6 +3,7 @@ import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUSBYMEMBER_RO_WITH from './GEORADIUSBYMEMBER_RO_WITH'; import { CommandArguments } from '../RESP/types'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUSBYMEMBER_RO WITH', () => { it('transformArguments', () => { @@ -10,7 +11,7 @@ describe('GEORADIUSBYMEMBER_RO WITH', () => { expectedReply.preserve = ['WITHDIST']; assert.deepEqual( - GEORADIUSBYMEMBER_RO_WITH.transformArguments('key', 'member', 3, 'm', [ + parseArgs(GEORADIUSBYMEMBER_RO_WITH, 'key', 'member', 3, 'm', [ GEO_REPLY_WITH.DISTANCE ]), expectedReply diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.ts index 5fb945a1f9..0683543801 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_RO_WITH.ts @@ -1,9 +1,13 @@ import { Command } from '../RESP/types'; -import GEORADIUSBYMEMBER_WITH, { transformGeoRadiusByMemberWithArguments } from './GEORADIUSBYMEMBER_WITH'; +import GEORADIUSBYMEMBER_WITH, { parseGeoRadiusByMemberWithArguments } from './GEORADIUSBYMEMBER_WITH'; export default { - FIRST_KEY_INDEX: GEORADIUSBYMEMBER_WITH.FIRST_KEY_INDEX, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments: transformGeoRadiusByMemberWithArguments.bind(undefined, 'GEORADIUSBYMEMBER_RO'), + parseCommand(...args: Parameters) { + const parser = args[0]; + parser.push('GEORADIUSBYMEMBER_RO'); + parseGeoRadiusByMemberWithArguments(...args); + }, transformReply: GEORADIUSBYMEMBER_WITH.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.spec.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.spec.ts index 3d44060f20..9edb08d1ea 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.spec.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUSBYMEMBER_STORE from './GEORADIUSBYMEMBER_STORE'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUSBYMEMBER STORE', () => { describe('transformArguments', () => { it('STORE', () => { assert.deepEqual( - GEORADIUSBYMEMBER_STORE.transformArguments('key', 'member', 3, 'm', 'destination'), + parseArgs(GEORADIUSBYMEMBER_STORE, 'key', 'member', 3, 'm', 'destination'), ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'STORE', 'destination'] ); }); it('STOREDIST', () => { assert.deepEqual( - GEORADIUSBYMEMBER_STORE.transformArguments('key', 'member', 3, 'm', 'destination', { + parseArgs(GEORADIUSBYMEMBER_STORE, 'key', 'member', 3, 'm', 'destination', { STOREDIST: true }), ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'STOREDIST', 'destination'] diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.ts index 9041996311..676df34dd5 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_STORE.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import GEORADIUSBYMEMBER, { transformGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER'; +import GEORADIUSBYMEMBER, { parseGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER'; import { GeoSearchOptions, GeoUnits } from './GEOSEARCH'; export interface GeoRadiusStoreOptions extends GeoSearchOptions { @@ -7,9 +8,9 @@ export interface GeoRadiusStoreOptions extends GeoSearchOptions { } export default { - FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX, IS_READ_ONLY: GEORADIUSBYMEMBER.IS_READ_ONLY, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, from: RedisArgument, radius: number, @@ -17,15 +18,16 @@ export default { destination: RedisArgument, options?: GeoRadiusStoreOptions ) { - const args = transformGeoRadiusByMemberArguments('GEORADIUSBYMEMBER', key, from, radius, unit, options); + parser.push('GEORADIUSBYMEMBER') + parseGeoRadiusByMemberArguments(parser, key, from, radius, unit, options); if (options?.STOREDIST) { - args.push('STOREDIST', destination); + parser.push('STOREDIST'); + parser.pushKey(destination); } else { - args.push('STORE', destination); + parser.push('STORE'); + parser.pushKey(destination); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.spec.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.spec.ts index ffe3b2efff..9d634d6065 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.spec.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.spec.ts @@ -3,6 +3,7 @@ import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUSBYMEMBER_WITH from './GEORADIUSBYMEMBER_WITH'; import { CommandArguments } from '../RESP/types'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUSBYMEMBER WITH', () => { it('transformArguments', () => { @@ -10,7 +11,7 @@ describe('GEORADIUSBYMEMBER WITH', () => { expectedReply.preserve = ['WITHDIST']; assert.deepEqual( - GEORADIUSBYMEMBER_WITH.transformArguments('key', 'member', 3, 'm', [ + parseArgs(GEORADIUSBYMEMBER_WITH, 'key', 'member', 3, 'm', [ GEO_REPLY_WITH.DISTANCE ]), expectedReply diff --git a/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.ts b/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.ts index be9472a438..eefae0b27a 100644 --- a/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.ts +++ b/packages/client/lib/commands/GEORADIUSBYMEMBER_WITH.ts @@ -1,10 +1,11 @@ -import { RedisArgument, CommandArguments, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, Command } from '../RESP/types'; import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER'; -import { GeoSearchOptions, GeoUnits, pushGeoSearchOptions } from './GEOSEARCH'; +import { GeoSearchOptions, GeoUnits, parseGeoSearchOptions } from './GEOSEARCH'; import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH'; -export function transformGeoRadiusByMemberWithArguments( - command: RedisArgument, +export function parseGeoRadiusByMemberWithArguments( + parser: CommandParser, key: RedisArgument, from: RedisArgument, radius: number, @@ -12,25 +13,27 @@ export function transformGeoRadiusByMemberWithArguments( replyWith: Array, options?: GeoSearchOptions ) { - const args: CommandArguments = [ - command, - key, - from, - radius.toString(), - unit - ]; + parser.pushKey(key); + parser.push(from, radius.toString(), unit); + parseGeoSearchOptions(parser, options); - pushGeoSearchOptions(args, options); - - args.push(...replyWith); - args.preserve = replyWith; - - return args; + parser.push(...replyWith); + parser.preserve = replyWith; } export default { - FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX, IS_READ_ONLY: GEORADIUSBYMEMBER.IS_READ_ONLY, - transformArguments: transformGeoRadiusByMemberWithArguments.bind(undefined, 'GEORADIUSBYMEMBER'), + parseCommand( + parser: CommandParser, + key: RedisArgument, + from: RedisArgument, + radius: number, + unit: GeoUnits, + replyWith: Array, + options?: GeoSearchOptions + ) { + parser.push('GEORADIUSBYMEMBER'); + parseGeoRadiusByMemberWithArguments(parser, key, from, radius, unit, replyWith, options); + }, transformReply: GEOSEARCH_WITH.transformReply } as const satisfies Command; \ No newline at end of file diff --git a/packages/client/lib/commands/GEORADIUS_RO.spec.ts b/packages/client/lib/commands/GEORADIUS_RO.spec.ts index 43a2ef1d58..917eba3ab8 100644 --- a/packages/client/lib/commands/GEORADIUS_RO.spec.ts +++ b/packages/client/lib/commands/GEORADIUS_RO.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUS_RO from './GEORADIUS_RO'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUS_RO', () => { it('transformArguments', () => { assert.deepEqual( - GEORADIUS_RO.transformArguments('key', { + parseArgs(GEORADIUS_RO, 'key', { longitude: 1, latitude: 2 }, 3, 'm'), diff --git a/packages/client/lib/commands/GEORADIUS_RO.ts b/packages/client/lib/commands/GEORADIUS_RO.ts index be8bb4b530..5db65d9dc9 100644 --- a/packages/client/lib/commands/GEORADIUS_RO.ts +++ b/packages/client/lib/commands/GEORADIUS_RO.ts @@ -1,9 +1,12 @@ import { Command } from '../RESP/types'; -import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS'; +import GEORADIUS, { parseGeoRadiusArguments } from './GEORADIUS'; export default { - FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments: transformGeoRadiusArguments.bind(undefined, 'GEORADIUS_RO'), + parseCommand(...args: Parameters) { + args[0].push('GEORADIUS_RO'); + parseGeoRadiusArguments(...args); + }, transformReply: GEORADIUS.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUS_RO_WITH.spec.ts b/packages/client/lib/commands/GEORADIUS_RO_WITH.spec.ts index cb0540d8a1..01d79954b6 100644 --- a/packages/client/lib/commands/GEORADIUS_RO_WITH.spec.ts +++ b/packages/client/lib/commands/GEORADIUS_RO_WITH.spec.ts @@ -3,6 +3,7 @@ import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUS_RO_WITH from './GEORADIUS_RO_WITH'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH'; import { CommandArguments } from '../RESP/types'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUS_RO WITH', () => { it('transformArguments', () => { @@ -10,7 +11,7 @@ describe('GEORADIUS_RO WITH', () => { expectedReply.preserve = ['WITHDIST']; assert.deepEqual( - GEORADIUS_RO_WITH.transformArguments('key', { + parseArgs(GEORADIUS_RO_WITH, 'key', { longitude: 1, latitude: 2 }, 3, 'm', [GEO_REPLY_WITH.DISTANCE]), diff --git a/packages/client/lib/commands/GEORADIUS_RO_WITH.ts b/packages/client/lib/commands/GEORADIUS_RO_WITH.ts index 37cf594ce9..cee1679382 100644 --- a/packages/client/lib/commands/GEORADIUS_RO_WITH.ts +++ b/packages/client/lib/commands/GEORADIUS_RO_WITH.ts @@ -1,9 +1,13 @@ import { Command } from '../RESP/types'; -import GEORADIUS_WITH, { transformGeoRadiusWithArguments } from './GEORADIUS_WITH'; +import { parseGeoRadiusWithArguments } from './GEORADIUS_WITH'; +import GEORADIUS_WITH from './GEORADIUS_WITH'; export default { - FIRST_KEY_INDEX: GEORADIUS_WITH.FIRST_KEY_INDEX, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS_RO'), + parseCommand(...args: Parameters) { + args[0].push('GEORADIUS_RO'); + parseGeoRadiusWithArguments(...args); + }, transformReply: GEORADIUS_WITH.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUS_STORE.spec.ts b/packages/client/lib/commands/GEORADIUS_STORE.spec.ts index 04a7d28aa9..9a9bcf37bc 100644 --- a/packages/client/lib/commands/GEORADIUS_STORE.spec.ts +++ b/packages/client/lib/commands/GEORADIUS_STORE.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUS_STORE from './GEORADIUS_STORE'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUS STORE', () => { describe('transformArguments', () => { it('STORE', () => { assert.deepEqual( - GEORADIUS_STORE.transformArguments('key', { + parseArgs(GEORADIUS_STORE, 'key', { longitude: 1, latitude: 2 }, 3, 'm', 'destination'), @@ -16,7 +17,7 @@ describe('GEORADIUS STORE', () => { it('STOREDIST', () => { assert.deepEqual( - GEORADIUS_STORE.transformArguments('key', { + parseArgs(GEORADIUS_STORE, 'key', { longitude: 1, latitude: 2 }, 3, 'm', 'destination', { diff --git a/packages/client/lib/commands/GEORADIUS_STORE.ts b/packages/client/lib/commands/GEORADIUS_STORE.ts index 3a553ebf8b..18459d4421 100644 --- a/packages/client/lib/commands/GEORADIUS_STORE.ts +++ b/packages/client/lib/commands/GEORADIUS_STORE.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS'; +import GEORADIUS, { parseGeoRadiusArguments } from './GEORADIUS'; import { GeoCoordinates, GeoSearchOptions, GeoUnits } from './GEOSEARCH'; export interface GeoRadiusStoreOptions extends GeoSearchOptions { @@ -7,9 +8,9 @@ export interface GeoRadiusStoreOptions extends GeoSearchOptions { } export default { - FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX, IS_READ_ONLY: GEORADIUS.IS_READ_ONLY, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, from: GeoCoordinates, radius: number, @@ -17,15 +18,15 @@ export default { destination: RedisArgument, options?: GeoRadiusStoreOptions ) { - const args = transformGeoRadiusArguments('GEORADIUS', key, from, radius, unit, options); - + parser.push('GEORADIUS'); + parseGeoRadiusArguments(parser, key, from, radius, unit, options); if (options?.STOREDIST) { - args.push('STOREDIST', destination); + parser.push('STOREDIST'); + parser.pushKey(destination); } else { - args.push('STORE', destination); + parser.push('STORE'); + parser.pushKey(destination); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEORADIUS_WITH.spec.ts b/packages/client/lib/commands/GEORADIUS_WITH.spec.ts index bdbfc9c1f3..f514c9be96 100644 --- a/packages/client/lib/commands/GEORADIUS_WITH.spec.ts +++ b/packages/client/lib/commands/GEORADIUS_WITH.spec.ts @@ -3,6 +3,7 @@ import testUtils, { GLOBAL } from '../test-utils'; import GEORADIUS_WITH from './GEORADIUS_WITH'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH'; import { CommandArguments } from '../RESP/types'; +import { parseArgs } from './generic-transformers'; describe('GEORADIUS WITH', () => { it('transformArguments', () => { @@ -10,7 +11,7 @@ describe('GEORADIUS WITH', () => { expectedReply.preserve = ['WITHDIST']; assert.deepEqual( - GEORADIUS_WITH.transformArguments('key', { + parseArgs(GEORADIUS_WITH, 'key', { longitude: 1, latitude: 2 }, 3, 'm', [GEO_REPLY_WITH.DISTANCE]), diff --git a/packages/client/lib/commands/GEORADIUS_WITH.ts b/packages/client/lib/commands/GEORADIUS_WITH.ts index d72d8d4932..ac4c8b7bb1 100644 --- a/packages/client/lib/commands/GEORADIUS_WITH.ts +++ b/packages/client/lib/commands/GEORADIUS_WITH.ts @@ -1,33 +1,36 @@ -import { CommandArguments, Command, RedisArgument } from '../RESP/types'; -import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS'; +import { CommandParser } from '../client/parser'; +import { Command, RedisArgument } from '../RESP/types'; +import GEORADIUS, { parseGeoRadiusArguments } from './GEORADIUS'; import { GeoCoordinates, GeoSearchOptions, GeoUnits } from './GEOSEARCH'; import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH'; -export function transformGeoRadiusWithArguments( - command: RedisArgument, +export function parseGeoRadiusWithArguments( + parser: CommandParser, key: RedisArgument, from: GeoCoordinates, radius: number, unit: GeoUnits, replyWith: Array, - options?: GeoSearchOptions + options?: GeoSearchOptions, ) { - const args: CommandArguments = transformGeoRadiusArguments( - command, - key, - from, - radius, - unit, - options - ); - args.push(...replyWith); - args.preserve = replyWith; - return args; + parseGeoRadiusArguments(parser, key, from, radius, unit, options) + parser.pushVariadic(replyWith); + parser.preserve = replyWith; } export default { - FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX, IS_READ_ONLY: GEORADIUS.IS_READ_ONLY, - transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS'), + parseCommand( + parser: CommandParser, + key: RedisArgument, + from: GeoCoordinates, + radius: number, + unit: GeoUnits, + replyWith: Array, + options?: GeoSearchOptions + ) { + parser.push('GEORADIUS'); + parseGeoRadiusWithArguments(parser, key, from, radius, unit, replyWith, options); + }, transformReply: GEOSEARCH_WITH.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEOSEARCH.spec.ts b/packages/client/lib/commands/GEOSEARCH.spec.ts index 49f076880a..4cd7e61a0a 100644 --- a/packages/client/lib/commands/GEOSEARCH.spec.ts +++ b/packages/client/lib/commands/GEOSEARCH.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOSEARCH from './GEOSEARCH'; +import { parseArgs } from './generic-transformers'; describe('GEOSEARCH', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,7 +9,7 @@ describe('GEOSEARCH', () => { describe('transformArguments', () => { it('FROMMEMBER, BYRADIUS, without options', () => { assert.deepEqual( - GEOSEARCH.transformArguments('key', 'member', { + parseArgs(GEOSEARCH, 'key', 'member', { radius: 1, unit: 'm' }), @@ -18,7 +19,7 @@ describe('GEOSEARCH', () => { it('FROMLONLAT, BYBOX, without options', () => { assert.deepEqual( - GEOSEARCH.transformArguments('key', { + parseArgs(GEOSEARCH, 'key', { longitude: 1, latitude: 2 }, { @@ -32,7 +33,7 @@ describe('GEOSEARCH', () => { it('with SORT', () => { assert.deepEqual( - GEOSEARCH.transformArguments('key', 'member', { + parseArgs(GEOSEARCH, 'key', 'member', { radius: 1, unit: 'm' }, { @@ -45,7 +46,7 @@ describe('GEOSEARCH', () => { describe('with COUNT', () => { it('number', () => { assert.deepEqual( - GEOSEARCH.transformArguments('key', 'member', { + parseArgs(GEOSEARCH, 'key', 'member', { radius: 1, unit: 'm' }, { @@ -57,7 +58,7 @@ describe('GEOSEARCH', () => { it('with ANY', () => { assert.deepEqual( - GEOSEARCH.transformArguments('key', 'member', { + parseArgs(GEOSEARCH, 'key', 'member', { radius: 1, unit: 'm' }, { diff --git a/packages/client/lib/commands/GEOSEARCH.ts b/packages/client/lib/commands/GEOSEARCH.ts index c4deaa37e6..8c77fd8923 100644 --- a/packages/client/lib/commands/GEOSEARCH.ts +++ b/packages/client/lib/commands/GEOSEARCH.ts @@ -1,4 +1,5 @@ -import { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export type GeoUnits = 'm' | 'km' | 'mi' | 'ft'; @@ -22,30 +23,33 @@ export interface GeoSearchByBox { export type GeoSearchBy = GeoSearchByRadius | GeoSearchByBox; -export function pushGeoSearchArguments( - args: CommandArguments, +export function parseGeoSearchArguments( + parser: CommandParser, key: RedisArgument, from: GeoSearchFrom, by: GeoSearchBy, - options?: GeoSearchOptions + options?: GeoSearchOptions, + store?: RedisArgument ) { - args.push(key); + if (store !== undefined) { + parser.pushKey(store); + } + + parser.pushKey(key); if (typeof from === 'string' || from instanceof Buffer) { - args.push('FROMMEMBER', from); + parser.push('FROMMEMBER', from); } else { - args.push('FROMLONLAT', from.longitude.toString(), from.latitude.toString()); + parser.push('FROMLONLAT', from.longitude.toString(), from.latitude.toString()); } if ('radius' in by) { - args.push('BYRADIUS', by.radius.toString(), by.unit); + parser.push('BYRADIUS', by.radius.toString(), by.unit); } else { - args.push('BYBOX', by.width.toString(), by.height.toString(), by.unit); + parser.push('BYBOX', by.width.toString(), by.height.toString(), by.unit); } - pushGeoSearchOptions(args, options); - - return args; + parseGeoSearchOptions(parser, options); } export type GeoCountArgument = number | { @@ -58,37 +62,38 @@ export interface GeoSearchOptions { COUNT?: GeoCountArgument; } -export function pushGeoSearchOptions( - args: CommandArguments, +export function parseGeoSearchOptions( + parser: CommandParser, options?: GeoSearchOptions ) { if (options?.SORT) { - args.push(options.SORT); + parser.push(options.SORT); } if (options?.COUNT) { if (typeof options.COUNT === 'number') { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } else { - args.push('COUNT', options.COUNT.value.toString()); + parser.push('COUNT', options.COUNT.value.toString()); if (options.COUNT.ANY) { - args.push('ANY'); + parser.push('ANY'); } } } } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, from: GeoSearchFrom, by: GeoSearchBy, options?: GeoSearchOptions ) { - return pushGeoSearchArguments(['GEOSEARCH'], key, from, by, options); + parser.push('GEOSEARCH'); + parseGeoSearchArguments(parser, key, from, by, options); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEOSEARCHSTORE.spec.ts b/packages/client/lib/commands/GEOSEARCHSTORE.spec.ts index c66d3e8e45..b8427ae041 100644 --- a/packages/client/lib/commands/GEOSEARCHSTORE.spec.ts +++ b/packages/client/lib/commands/GEOSEARCHSTORE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOSEARCHSTORE from './GEOSEARCHSTORE'; +import { parseArgs } from './generic-transformers'; describe('GEOSEARCHSTORE', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,7 +9,7 @@ describe('GEOSEARCHSTORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - GEOSEARCHSTORE.transformArguments('source', 'destination', 'member', { + parseArgs(GEOSEARCHSTORE, 'source', 'destination', 'member', { radius: 1, unit: 'm' }), @@ -18,7 +19,7 @@ describe('GEOSEARCHSTORE', () => { it('with STOREDIST', () => { assert.deepEqual( - GEOSEARCHSTORE.transformArguments('destination', 'source', 'member', { + parseArgs(GEOSEARCHSTORE, 'destination', 'source', 'member', { radius: 1, unit: 'm' }, { diff --git a/packages/client/lib/commands/GEOSEARCHSTORE.ts b/packages/client/lib/commands/GEOSEARCHSTORE.ts index 1563556021..eb8e12abe6 100644 --- a/packages/client/lib/commands/GEOSEARCHSTORE.ts +++ b/packages/client/lib/commands/GEOSEARCHSTORE.ts @@ -1,27 +1,27 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './GEOSEARCH'; +import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, parseGeoSearchArguments } from './GEOSEARCH'; export interface GeoSearchStoreOptions extends GeoSearchOptions { STOREDIST?: boolean; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, source: RedisArgument, from: GeoSearchFrom, by: GeoSearchBy, options?: GeoSearchStoreOptions ) { - const args = pushGeoSearchArguments(['GEOSEARCHSTORE', destination], source, from, by, options); + parser.push('GEOSEARCHSTORE'); + parseGeoSearchArguments(parser, source, from, by, options, destination); if (options?.STOREDIST) { - args.push('STOREDIST'); + parser.push('STOREDIST'); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GEOSEARCH_WITH.spec.ts b/packages/client/lib/commands/GEOSEARCH_WITH.spec.ts index e27fb295aa..973e5d5827 100644 --- a/packages/client/lib/commands/GEOSEARCH_WITH.spec.ts +++ b/packages/client/lib/commands/GEOSEARCH_WITH.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GEOSEARCH_WITH, { GEO_REPLY_WITH } from './GEOSEARCH_WITH'; import { CommandArguments } from '../RESP/types'; +import { parseArgs } from './generic-transformers'; describe('GEOSEARCH WITH', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -11,7 +12,7 @@ describe('GEOSEARCH WITH', () => { expectedReply.preserve = ['WITHDIST']; assert.deepEqual( - GEOSEARCH_WITH.transformArguments('key', 'member', { + parseArgs(GEOSEARCH_WITH, 'key', 'member', { radius: 1, unit: 'm' }, [GEO_REPLY_WITH.DISTANCE]), diff --git a/packages/client/lib/commands/GEOSEARCH_WITH.ts b/packages/client/lib/commands/GEOSEARCH_WITH.ts index 19088230f0..65e3975b72 100644 --- a/packages/client/lib/commands/GEOSEARCH_WITH.ts +++ b/packages/client/lib/commands/GEOSEARCH_WITH.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, NumberReply, DoubleReply, UnwrapReply, Command } from '../RESP/types'; import GEOSEARCH, { GeoSearchBy, GeoSearchFrom, GeoSearchOptions } from './GEOSEARCH'; @@ -20,19 +21,18 @@ export interface GeoReplyWithMember { } export default { - FIRST_KEY_INDEX: GEOSEARCH.FIRST_KEY_INDEX, IS_READ_ONLY: GEOSEARCH.IS_READ_ONLY, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, from: GeoSearchFrom, by: GeoSearchBy, replyWith: Array, options?: GeoSearchOptions ) { - const args = GEOSEARCH.transformArguments(key, from, by, options); - args.push(...replyWith); - args.preserve = replyWith; - return args; + GEOSEARCH.parseCommand(parser, key, from, by, options); + parser.push(...replyWith); + parser.preserve = replyWith; }, transformReply( reply: UnwrapReply]>>>, diff --git a/packages/client/lib/commands/GET.spec.ts b/packages/client/lib/commands/GET.spec.ts index 4bd7418322..3e630d03e0 100644 --- a/packages/client/lib/commands/GET.spec.ts +++ b/packages/client/lib/commands/GET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import GET from './GET'; describe('GET', () => { it('transformArguments', () => { assert.deepEqual( - GET.transformArguments('key'), + parseArgs(GET, 'key'), ['GET', 'key'] ); }); diff --git a/packages/client/lib/commands/GET.ts b/packages/client/lib/commands/GET.ts index bb3db4f76d..ca013752ae 100644 --- a/packages/client/lib/commands/GET.ts +++ b/packages/client/lib/commands/GET.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['GET', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('GET'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GETBIT.spec.ts b/packages/client/lib/commands/GETBIT.spec.ts index ac39222b91..66d2798313 100644 --- a/packages/client/lib/commands/GETBIT.spec.ts +++ b/packages/client/lib/commands/GETBIT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GETBIT from './GETBIT'; +import { parseArgs } from './generic-transformers'; describe('GETBIT', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - GETBIT.transformArguments('key', 0), + parseArgs(GETBIT, 'key', 0), ['GETBIT', 'key', '0'] ); }); diff --git a/packages/client/lib/commands/GETBIT.ts b/packages/client/lib/commands/GETBIT.ts index d8ece8f523..023ba0fb60 100644 --- a/packages/client/lib/commands/GETBIT.ts +++ b/packages/client/lib/commands/GETBIT.ts @@ -1,11 +1,14 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; import { BitValue } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, offset: number) { - return ['GETBIT', key, offset.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, offset: number) { + parser.push('GETBIT'); + parser.pushKey(key); + parser.push(offset.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GETDEL.spec.ts b/packages/client/lib/commands/GETDEL.spec.ts index 311f15e554..15ad591800 100644 --- a/packages/client/lib/commands/GETDEL.spec.ts +++ b/packages/client/lib/commands/GETDEL.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GETDEL from './GETDEL'; +import { parseArgs } from './generic-transformers'; describe('GETDEL', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - GETDEL.transformArguments('key'), + parseArgs(GETDEL, 'key'), ['GETDEL', 'key'] ); }); diff --git a/packages/client/lib/commands/GETDEL.ts b/packages/client/lib/commands/GETDEL.ts index c11fd047df..a39014109f 100644 --- a/packages/client/lib/commands/GETDEL.ts +++ b/packages/client/lib/commands/GETDEL.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['GETDEL', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('GETDEL'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GETEX.spec.ts b/packages/client/lib/commands/GETEX.spec.ts index 302d034b96..5965d8f196 100644 --- a/packages/client/lib/commands/GETEX.spec.ts +++ b/packages/client/lib/commands/GETEX.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GETEX from './GETEX'; +import { parseArgs } from './generic-transformers'; describe('GETEX', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,7 +9,7 @@ describe('GETEX', () => { describe('transformArguments', () => { it('EX | PX', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { type: 'EX', value: 1 }), @@ -18,7 +19,7 @@ describe('GETEX', () => { it('EX (backwards compatibility)', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { EX: 1 }), ['GETEX', 'key', 'EX', '1'] @@ -27,7 +28,7 @@ describe('GETEX', () => { it('PX (backwards compatibility)', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { PX: 1 }), ['GETEX', 'key', 'PX', '1'] @@ -37,7 +38,7 @@ describe('GETEX', () => { describe('EXAT | PXAT', () => { it('number', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { type: 'EXAT', value: 1 }), @@ -48,7 +49,7 @@ describe('GETEX', () => { it('date', () => { const d = new Date(); assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { EXAT: d }), ['GETEX', 'key', 'EXAT', Math.floor(d.getTime() / 1000).toString()] @@ -59,7 +60,7 @@ describe('GETEX', () => { describe('EXAT (backwards compatibility)', () => { it('number', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { EXAT: 1 }), ['GETEX', 'key', 'EXAT', '1'] @@ -69,7 +70,7 @@ describe('GETEX', () => { it('date', () => { const d = new Date(); assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { EXAT: d }), ['GETEX', 'key', 'EXAT', Math.floor(d.getTime() / 1000).toString()] @@ -80,7 +81,7 @@ describe('GETEX', () => { describe('PXAT (backwards compatibility)', () => { it('number', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { PXAT: 1 }), ['GETEX', 'key', 'PXAT', '1'] @@ -90,7 +91,7 @@ describe('GETEX', () => { it('date', () => { const d = new Date(); assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { PXAT: d }), ['GETEX', 'key', 'PXAT', d.getTime().toString()] @@ -100,7 +101,7 @@ describe('GETEX', () => { it('PERSIST (backwards compatibility)', () => { assert.deepEqual( - GETEX.transformArguments('key', { + parseArgs(GETEX, 'key', { PERSIST: true }), ['GETEX', 'key', 'PERSIST'] diff --git a/packages/client/lib/commands/GETEX.ts b/packages/client/lib/commands/GETEX.ts index 8244350edd..e5ae0b691a 100644 --- a/packages/client/lib/commands/GETEX.ts +++ b/packages/client/lib/commands/GETEX.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; import { transformEXAT, transformPXAT } from './generic-transformers'; @@ -37,42 +38,40 @@ export type GetExOptions = { }; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options: GetExOptions) { - const args = ['GETEX', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options: GetExOptions) { + parser.push('GETEX'); + parser.pushKey(key); if ('type' in options) { switch (options.type) { case 'EX': case 'PX': - args.push(options.type, options.value.toString()); + parser.push(options.type, options.value.toString()); break; case 'EXAT': case 'PXAT': - args.push(options.type, transformEXAT(options.value)); + parser.push(options.type, transformEXAT(options.value)); break; case 'PERSIST': - args.push('PERSIST'); + parser.push('PERSIST'); break; } } else { if ('EX' in options) { - args.push('EX', options.EX.toString()); + parser.push('EX', options.EX.toString()); } else if ('PX' in options) { - args.push('PX', options.PX.toString()); + parser.push('PX', options.PX.toString()); } else if ('EXAT' in options) { - args.push('EXAT', transformEXAT(options.EXAT)); + parser.push('EXAT', transformEXAT(options.EXAT)); } else if ('PXAT' in options) { - args.push('PXAT', transformPXAT(options.PXAT)); + parser.push('PXAT', transformPXAT(options.PXAT)); } else { // PERSIST - args.push('PERSIST'); + parser.push('PERSIST'); } } - - return args; }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GETRANGE.spec.ts b/packages/client/lib/commands/GETRANGE.spec.ts index 2aac1ca16d..8a8e7dde03 100644 --- a/packages/client/lib/commands/GETRANGE.spec.ts +++ b/packages/client/lib/commands/GETRANGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GETRANGE from './GETRANGE'; +import { parseArgs } from './generic-transformers'; describe('GETRANGE', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - GETRANGE.transformArguments('key', 0, -1), + parseArgs(GETRANGE, 'key', 0, -1), ['GETRANGE', 'key', '0', '-1'] ); }); diff --git a/packages/client/lib/commands/GETRANGE.ts b/packages/client/lib/commands/GETRANGE.ts index e5357cd120..ce0db6e3c0 100644 --- a/packages/client/lib/commands/GETRANGE.ts +++ b/packages/client/lib/commands/GETRANGE.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, start: number, end: number) { - return ['GETRANGE', key, start.toString(), end.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, start: number, end: number) { + parser.push('GETRANGE'); + parser.pushKey(key); + parser.push(start.toString(), end.toString()); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/GETSET.spec.ts b/packages/client/lib/commands/GETSET.spec.ts index 6583ec34f7..5b162c16cc 100644 --- a/packages/client/lib/commands/GETSET.spec.ts +++ b/packages/client/lib/commands/GETSET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GETSET from './GETSET'; +import { parseArgs } from './generic-transformers'; describe('GETSET', () => { it('transformArguments', () => { assert.deepEqual( - GETSET.transformArguments('key', 'value'), + parseArgs(GETSET, 'key', 'value'), ['GETSET', 'key', 'value'] ); }); diff --git a/packages/client/lib/commands/GETSET.ts b/packages/client/lib/commands/GETSET.ts index bbe920181b..1b3312548e 100644 --- a/packages/client/lib/commands/GETSET.ts +++ b/packages/client/lib/commands/GETSET.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, value: RedisArgument) { - return ['GETSET', key, value]; + parseCommand(parser: CommandParser, key: RedisArgument, value: RedisArgument) { + parser.push('GETSET'); + parser.pushKey(key); + parser.push(value); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HDEL.spec.ts b/packages/client/lib/commands/HDEL.spec.ts index 9f69485d9f..767d916e14 100644 --- a/packages/client/lib/commands/HDEL.spec.ts +++ b/packages/client/lib/commands/HDEL.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HDEL from './HDEL'; +import { parseArgs } from './generic-transformers'; describe('HDEL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HDEL.transformArguments('key', 'field'), + parseArgs(HDEL, 'key', 'field'), ['HDEL', 'key', 'field'] ); }); it('array', () => { assert.deepEqual( - HDEL.transformArguments('key', ['1', '2']), + parseArgs(HDEL, 'key', ['1', '2']), ['HDEL', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/HDEL.ts b/packages/client/lib/commands/HDEL.ts index 64aa55edda..713d19a9b2 100644 --- a/packages/client/lib/commands/HDEL.ts +++ b/packages/client/lib/commands/HDEL.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, field: RedisVariadicArgument) { - return pushVariadicArguments(['HDEL', key], field); + parseCommand(parser: CommandParser, key: RedisArgument, field: RedisVariadicArgument) { + parser.push('HDEL'); + parser.pushKey(key); + parser.pushVariadic(field); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HELLO.spec.ts b/packages/client/lib/commands/HELLO.spec.ts index f7f117f18c..5d11be344c 100644 --- a/packages/client/lib/commands/HELLO.spec.ts +++ b/packages/client/lib/commands/HELLO.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HELLO from './HELLO'; +import { parseArgs } from './generic-transformers'; describe('HELLO', () => { testUtils.isVersionGreaterThanHook([6]); @@ -8,21 +9,21 @@ describe('HELLO', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - HELLO.transformArguments(), + parseArgs(HELLO), ['HELLO'] ); }); it('with protover', () => { assert.deepEqual( - HELLO.transformArguments(3), + parseArgs(HELLO, 3), ['HELLO', '3'] ); }); it('with protover, AUTH', () => { assert.deepEqual( - HELLO.transformArguments(3, { + parseArgs(HELLO, 3, { AUTH: { username: 'username', password: 'password' @@ -34,7 +35,7 @@ describe('HELLO', () => { it('with protover, SETNAME', () => { assert.deepEqual( - HELLO.transformArguments(3, { + parseArgs(HELLO, 3, { SETNAME: 'name' }), ['HELLO', '3', 'SETNAME', 'name'] @@ -43,7 +44,7 @@ describe('HELLO', () => { it('with protover, AUTH, SETNAME', () => { assert.deepEqual( - HELLO.transformArguments(3, { + parseArgs(HELLO, 3, { AUTH: { username: 'username', password: 'password' diff --git a/packages/client/lib/commands/HELLO.ts b/packages/client/lib/commands/HELLO.ts index 0fb2960d02..5d25998f98 100644 --- a/packages/client/lib/commands/HELLO.ts +++ b/packages/client/lib/commands/HELLO.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, RespVersions, TuplesToMapReply, BlobStringReply, NumberReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; export interface HelloOptions { @@ -20,14 +21,14 @@ export type HelloReply = TuplesToMapReply<[ ]>; export default { - transformArguments(protover?: RespVersions, options?: HelloOptions) { - const args: Array = ['HELLO']; + parseCommand(parser: CommandParser, protover?: RespVersions, options?: HelloOptions) { + parser.push('HELLO'); if (protover) { - args.push(protover.toString()); + parser.push(protover.toString()); if (options?.AUTH) { - args.push( + parser.push( 'AUTH', options.AUTH.username, options.AUTH.password @@ -35,14 +36,12 @@ export default { } if (options?.SETNAME) { - args.push( + parser.push( 'SETNAME', options.SETNAME ); } } - - return args; }, transformReply: { 2: (reply: UnwrapReply>) => ({ diff --git a/packages/client/lib/commands/HEXISTS.spec.ts b/packages/client/lib/commands/HEXISTS.spec.ts index 69ca6fa765..acd462ab7e 100644 --- a/packages/client/lib/commands/HEXISTS.spec.ts +++ b/packages/client/lib/commands/HEXISTS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HEXISTS from './HEXISTS'; +import { parseArgs } from './generic-transformers'; describe('HEXISTS', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - HEXISTS.transformArguments('key', 'field'), + parseArgs(HEXISTS, 'key', 'field'), ['HEXISTS', 'key', 'field'] ); }); diff --git a/packages/client/lib/commands/HEXISTS.ts b/packages/client/lib/commands/HEXISTS.ts index dc7e937ee7..9bb517b7df 100644 --- a/packages/client/lib/commands/HEXISTS.ts +++ b/packages/client/lib/commands/HEXISTS.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, field: RedisArgument) { - return ['HEXISTS', key, field]; + parseCommand(parser: CommandParser, key: RedisArgument, field: RedisArgument) { + parser.push('HEXISTS'); + parser.pushKey(key); + parser.push(field); }, transformReply: undefined as unknown as () => NumberReply<0 | 1> } as const satisfies Command; diff --git a/packages/client/lib/commands/HEXPIRE.spec.ts b/packages/client/lib/commands/HEXPIRE.spec.ts index 71c48b7e88..d28cc065ec 100644 --- a/packages/client/lib/commands/HEXPIRE.spec.ts +++ b/packages/client/lib/commands/HEXPIRE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HEXPIRE from './HEXPIRE'; +import { parseArgs } from './generic-transformers'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; describe('HEXPIRE', () => { @@ -9,21 +10,21 @@ describe('HEXPIRE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HEXPIRE.transformArguments('key', 'field', 1), + parseArgs(HEXPIRE, 'key', 'field', 1), ['HEXPIRE', 'key', '1', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HEXPIRE.transformArguments('key', ['field1', 'field2'], 1), + parseArgs(HEXPIRE, 'key', ['field1', 'field2'], 1), ['HEXPIRE', 'key', '1', 'FIELDS', '2', 'field1', 'field2'] ); }); it('with set option', () => { assert.deepEqual( - HEXPIRE.transformArguments('key', ['field1'], 1, 'NX'), + parseArgs(HEXPIRE, 'key', ['field1'], 1, 'NX'), ['HEXPIRE', 'key', '1', 'NX', 'FIELDS', '1', 'field1'] ); }); diff --git a/packages/client/lib/commands/HEXPIRE.ts b/packages/client/lib/commands/HEXPIRE.ts index 34b52c1db6..55e2f5a9be 100644 --- a/packages/client/lib/commands/HEXPIRE.ts +++ b/packages/client/lib/commands/HEXPIRE.ts @@ -1,5 +1,6 @@ -import { Command, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument } from './generic-transformers'; +import { CommandParser } from '../client/parser'; +import { ArrayReply, Command, RedisArgument } from '../RESP/types'; +import { RedisVariadicArgument } from './generic-transformers'; export const HASH_EXPIRATION = { /** The field does not exist */ @@ -11,25 +12,28 @@ export const HASH_EXPIRATION = { /** Field deleted because the specified expiration time is in the past */ DELETED: 2 } as const; - + export type HashExpiration = typeof HASH_EXPIRATION[keyof typeof HASH_EXPIRATION]; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, - fields: RedisArgument | Array, + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument, seconds: number, - mode?: 'NX' | 'XX' | 'GT' | 'LT', + mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['HEXPIRE', key, seconds.toString()]; - + parser.push('HEXPIRE'); + parser.pushKey(key); + parser.push(seconds.toString()); + if (mode) { - args.push(mode); + parser.push(mode); } - args.push('FIELDS'); + parser.push('FIELDS'); - return pushVariadicArgument(args, fields); + parser.pushVariadicWithLength(fields); }, - transformReply: undefined as unknown as () => Array + transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HEXPIREAT.spec.ts b/packages/client/lib/commands/HEXPIREAT.spec.ts index 1f87300214..c7cc9fe749 100644 --- a/packages/client/lib/commands/HEXPIREAT.spec.ts +++ b/packages/client/lib/commands/HEXPIREAT.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HEXPIREAT from './HEXPIREAT'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HEXPIREAT', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,14 +10,14 @@ describe('HEXPIREAT', () => { describe('transformArguments', () => { it('string + number', () => { assert.deepEqual( - HEXPIREAT.transformArguments('key', 'field', 1), + parseArgs(HEXPIREAT, 'key', 'field', 1), ['HEXPIREAT', 'key', '1', 'FIELDS', '1', 'field'] ); }); it('array + number', () => { assert.deepEqual( - HEXPIREAT.transformArguments('key', ['field1', 'field2'], 1), + parseArgs(HEXPIREAT, 'key', ['field1', 'field2'], 1), ['HEXPIREAT', 'key', '1', 'FIELDS', '2', 'field1', 'field2'] ); }); @@ -25,14 +26,14 @@ describe('HEXPIREAT', () => { const d = new Date(); assert.deepEqual( - HEXPIREAT.transformArguments('key', ['field1'], d), + parseArgs(HEXPIREAT, 'key', ['field1'], d), ['HEXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString(), 'FIELDS', '1', 'field1'] ); }); it('with set option', () => { assert.deepEqual( - HEXPIREAT.transformArguments('key', 'field1', 1, 'GT'), + parseArgs(HEXPIREAT, 'key', 'field1', 1, 'GT'), ['HEXPIREAT', 'key', '1', 'GT', 'FIELDS', '1', 'field1'] ); }); diff --git a/packages/client/lib/commands/HEXPIREAT.ts b/packages/client/lib/commands/HEXPIREAT.ts index 5a49951f1c..1370f2ecd6 100644 --- a/packages/client/lib/commands/HEXPIREAT.ts +++ b/packages/client/lib/commands/HEXPIREAT.ts @@ -1,28 +1,26 @@ -import { Command, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument, transformEXAT } from './generic-transformers'; -import { HashExpiration } from './HEXPIRE'; +import { CommandParser } from '../client/parser'; +import { RedisVariadicArgument, transformEXAT } from './generic-transformers'; +import { ArrayReply, Command, NumberReply, RedisArgument } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, fields: RedisVariadicArgument, timestamp: number | Date, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = [ - 'HEXPIREAT', - key, - transformEXAT(timestamp) - ]; - + parser.push('HEXPIREAT'); + parser.pushKey(key); + parser.push(transformEXAT(timestamp)); + if (mode) { - args.push(mode); + parser.push(mode); } - - args.push('FIELDS') - - return pushVariadicArgument(args, fields); + + parser.push('FIELDS') + + parser.pushVariadicWithLength(fields); }, - transformReply: undefined as unknown as () => Array + transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HEXPIRETIME.spec.ts b/packages/client/lib/commands/HEXPIRETIME.spec.ts index 2335ec9172..32a8730e8a 100644 --- a/packages/client/lib/commands/HEXPIRETIME.spec.ts +++ b/packages/client/lib/commands/HEXPIRETIME.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HEXPIRETIME, { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HEXPIRETIME', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -8,14 +9,14 @@ describe('HEXPIRETIME', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HEXPIRETIME.transformArguments('key', 'field'), + parseArgs(HEXPIRETIME, 'key', 'field'), ['HEXPIRETIME', 'key', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HEXPIRETIME.transformArguments('key', ['field1', 'field2']), + parseArgs(HEXPIRETIME, 'key', ['field1', 'field2']), ['HEXPIRETIME', 'key', 'FIELDS', '2', 'field1', 'field2'] ); }); diff --git a/packages/client/lib/commands/HEXPIRETIME.ts b/packages/client/lib/commands/HEXPIRETIME.ts index 7edf130900..697d327db1 100644 --- a/packages/client/lib/commands/HEXPIRETIME.ts +++ b/packages/client/lib/commands/HEXPIRETIME.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NumberReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export const HASH_EXPIRATION_TIME = { /** The field does not exist */ @@ -9,10 +10,16 @@ export const HASH_EXPIRATION_TIME = { } as const; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, fields: RedisVariadicArgument) { - return pushVariadicArgument(['HEXPIRETIME', key, 'FIELDS'], fields); + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument + ) { + parser.push('HEXPIRETIME'); + parser.pushKey(key); + parser.push('FIELDS'); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HGET.spec.ts b/packages/client/lib/commands/HGET.spec.ts index 397f22b560..47061876ae 100644 --- a/packages/client/lib/commands/HGET.spec.ts +++ b/packages/client/lib/commands/HGET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HGET from './HGET'; +import { parseArgs } from './generic-transformers'; describe('HGET', () => { it('transformArguments', () => { assert.deepEqual( - HGET.transformArguments('key', 'field'), + parseArgs(HGET, 'key', 'field'), ['HGET', 'key', 'field'] ); }); diff --git a/packages/client/lib/commands/HGET.ts b/packages/client/lib/commands/HGET.ts index d83f84e24f..fcd9334eb0 100644 --- a/packages/client/lib/commands/HGET.ts +++ b/packages/client/lib/commands/HGET.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, field: RedisArgument) { - return ['HGET', key, field]; + parseCommand(parser: CommandParser, key: RedisArgument, field: RedisArgument) { + parser.push('HGET'); + parser.pushKey(key); + parser.push(field); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HGETALL.ts b/packages/client/lib/commands/HGETALL.ts index f1f0ac50bc..a2c3011c4c 100644 --- a/packages/client/lib/commands/HGETALL.ts +++ b/packages/client/lib/commands/HGETALL.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, MapReply, BlobStringReply, Command } from '../RESP/types'; import { transformTuplesReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['HGETALL', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('HGETALL'); + parser.pushKey(key); }, TRANSFORM_LEGACY_REPLY: true, transformReply: { diff --git a/packages/client/lib/commands/HINCRBY.spec.ts b/packages/client/lib/commands/HINCRBY.spec.ts index 7718fe955e..ad382d97a9 100644 --- a/packages/client/lib/commands/HINCRBY.spec.ts +++ b/packages/client/lib/commands/HINCRBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HINCRBY from './HINCRBY'; +import { parseArgs } from './generic-transformers'; describe('HINCRBY', () => { it('transformArguments', () => { assert.deepEqual( - HINCRBY.transformArguments('key', 'field', 1), + parseArgs(HINCRBY, 'key', 'field', 1), ['HINCRBY', 'key', 'field', '1'] ); }); diff --git a/packages/client/lib/commands/HINCRBY.ts b/packages/client/lib/commands/HINCRBY.ts index cb7f62ebef..3638e408f7 100644 --- a/packages/client/lib/commands/HINCRBY.ts +++ b/packages/client/lib/commands/HINCRBY.ts @@ -1,18 +1,16 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, field: RedisArgument, increment: number ) { - return [ - 'HINCRBY', - key, - field, - increment.toString() - ]; + parser.push('HINCRBY'); + parser.pushKey(key); + parser.push(field, increment.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HINCRBYFLOAT.spec.ts b/packages/client/lib/commands/HINCRBYFLOAT.spec.ts index 6c265dc6d1..2edbd6f947 100644 --- a/packages/client/lib/commands/HINCRBYFLOAT.spec.ts +++ b/packages/client/lib/commands/HINCRBYFLOAT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HINCRBYFLOAT from './HINCRBYFLOAT'; +import { parseArgs } from './generic-transformers'; describe('HINCRBYFLOAT', () => { it('transformArguments', () => { assert.deepEqual( - HINCRBYFLOAT.transformArguments('key', 'field', 1.5), + parseArgs(HINCRBYFLOAT, 'key', 'field', 1.5), ['HINCRBYFLOAT', 'key', 'field', '1.5'] ); }); diff --git a/packages/client/lib/commands/HINCRBYFLOAT.ts b/packages/client/lib/commands/HINCRBYFLOAT.ts index a4eea75c82..6d527583c7 100644 --- a/packages/client/lib/commands/HINCRBYFLOAT.ts +++ b/packages/client/lib/commands/HINCRBYFLOAT.ts @@ -1,18 +1,16 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, field: RedisArgument, increment: number ) { - return [ - 'HINCRBYFLOAT', - key, - field, - increment.toString() - ]; + parser.push('HINCRBYFLOAT'); + parser.pushKey(key); + parser.push(field, increment.toString()); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HKEYS.spec.ts b/packages/client/lib/commands/HKEYS.spec.ts index dada7b4d6f..58445696d2 100644 --- a/packages/client/lib/commands/HKEYS.spec.ts +++ b/packages/client/lib/commands/HKEYS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HKEYS from './HKEYS'; +import { parseArgs } from './generic-transformers'; describe('HKEYS', () => { it('transformArguments', () => { assert.deepEqual( - HKEYS.transformArguments('key'), + parseArgs(HKEYS, 'key'), ['HKEYS', 'key'] ); }); diff --git a/packages/client/lib/commands/HKEYS.ts b/packages/client/lib/commands/HKEYS.ts index 00af43f7a4..f07a1ac127 100644 --- a/packages/client/lib/commands/HKEYS.ts +++ b/packages/client/lib/commands/HKEYS.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['HKEYS', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('HKEYS') + parser.pushKey(key); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HLEN.spec.ts b/packages/client/lib/commands/HLEN.spec.ts index 2457a26129..640e461ad0 100644 --- a/packages/client/lib/commands/HLEN.spec.ts +++ b/packages/client/lib/commands/HLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HLEN from './HLEN'; +import { parseArgs } from './generic-transformers'; describe('HLEN', () => { it('transformArguments', () => { assert.deepEqual( - HLEN.transformArguments('key'), + parseArgs(HLEN, 'key'), ['HLEN', 'key'] ); }); diff --git a/packages/client/lib/commands/HLEN.ts b/packages/client/lib/commands/HLEN.ts index 8f156d303e..e3b89da3e7 100644 --- a/packages/client/lib/commands/HLEN.ts +++ b/packages/client/lib/commands/HLEN.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['HLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('HLEN'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HMGET.spec.ts b/packages/client/lib/commands/HMGET.spec.ts index 99d94a6d37..8cc90e4abd 100644 --- a/packages/client/lib/commands/HMGET.spec.ts +++ b/packages/client/lib/commands/HMGET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HMGET from './HMGET'; +import { parseArgs } from './generic-transformers'; describe('HMGET', () => { - describe('transformArguments', () => { + describe('parseCommand', () => { it('string', () => { assert.deepEqual( - HMGET.transformArguments('key', 'field'), + parseArgs(HMGET, 'key', 'field'), ['HMGET', 'key', 'field'] ); }); it('array', () => { assert.deepEqual( - HMGET.transformArguments('key', ['field1', 'field2']), + parseArgs(HMGET, 'key', ['field1', 'field2']), ['HMGET', 'key', 'field1', 'field2'] ); }); diff --git a/packages/client/lib/commands/HMGET.ts b/packages/client/lib/commands/HMGET.ts index df28a64be0..51ba937339 100644 --- a/packages/client/lib/commands/HMGET.ts +++ b/packages/client/lib/commands/HMGET.ts @@ -1,14 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, NullReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - fields: RedisVariadicArgument - ) { - return pushVariadicArguments(['HMGET', key], fields); + parseCommand(parser: CommandParser, key: RedisArgument, fields: RedisVariadicArgument) { + parser.push('HMGET'); + parser.pushKey(key); + parser.pushVariadic(fields); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HPERSIST.spec.ts b/packages/client/lib/commands/HPERSIST.spec.ts index 05e225e8ea..0b317977cb 100644 --- a/packages/client/lib/commands/HPERSIST.spec.ts +++ b/packages/client/lib/commands/HPERSIST.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HPERSIST from './HPERSIST'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HPERSIST', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,14 +10,14 @@ describe('HPERSIST', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HPERSIST.transformArguments('key', 'field'), + parseArgs(HPERSIST, 'key', 'field'), ['HPERSIST', 'key', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HPERSIST.transformArguments('key', ['field1', 'field2']), + parseArgs(HPERSIST, 'key', ['field1', 'field2']), ['HPERSIST', 'key', 'FIELDS', '2', 'field1', 'field2'] ); }); diff --git a/packages/client/lib/commands/HPERSIST.ts b/packages/client/lib/commands/HPERSIST.ts index 3843fd80a5..fd0f320e65 100644 --- a/packages/client/lib/commands/HPERSIST.ts +++ b/packages/client/lib/commands/HPERSIST.ts @@ -1,11 +1,17 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, NumberReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - IS_READ_ONLY: true, - transformArguments(key: RedisArgument, fields: RedisVariadicArgument) { - return pushVariadicArgument(['HPERSIST', key, 'FIELDS'], fields); + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument + ) { + parser.push('HPERSIST'); + parser.pushKey(key); + parser.push('FIELDS'); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HPEXPIRE.spec.ts b/packages/client/lib/commands/HPEXPIRE.spec.ts index febcb0bc96..2f68fb9b7f 100644 --- a/packages/client/lib/commands/HPEXPIRE.spec.ts +++ b/packages/client/lib/commands/HPEXPIRE.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HPEXPIRE from './HPEXPIRE'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HEXPIRE', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,21 +10,21 @@ describe('HEXPIRE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HPEXPIRE.transformArguments('key', 'field', 1), + parseArgs(HPEXPIRE, 'key', 'field', 1), ['HPEXPIRE', 'key', '1', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HPEXPIRE.transformArguments('key', ['field1', 'field2'], 1), + parseArgs(HPEXPIRE, 'key', ['field1', 'field2'], 1), ['HPEXPIRE', 'key', '1', 'FIELDS', '2', 'field1', 'field2'] ); }); it('with set option', () => { assert.deepEqual( - HPEXPIRE.transformArguments('key', ['field1'], 1, 'NX'), + parseArgs(HPEXPIRE, 'key', ['field1'], 1, 'NX'), ['HPEXPIRE', 'key', '1', 'NX', 'FIELDS', '1', 'field1'] ); }); diff --git a/packages/client/lib/commands/HPEXPIRE.ts b/packages/client/lib/commands/HPEXPIRE.ts index 58624f9163..34513c34e3 100644 --- a/packages/client/lib/commands/HPEXPIRE.ts +++ b/packages/client/lib/commands/HPEXPIRE.ts @@ -1,24 +1,27 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; -import { HashExpiration } from "./HEXPIRE"; +import { RedisVariadicArgument } from './generic-transformers'; +import { HashExpiration } from './HEXPIRE'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, fields: RedisVariadicArgument, ms: number, mode?: 'NX' | 'XX' | 'GT' | 'LT', ) { - const args = ['HPEXPIRE', key, ms.toString()]; - + parser.push('HPEXPIRE'); + parser.pushKey(key); + parser.push(ms.toString()); + if (mode) { - args.push(mode); + parser.push(mode); } - - args.push('FIELDS') - - return pushVariadicArgument(args, fields); + + parser.push('FIELDS') + + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HPEXPIREAT.spec.ts b/packages/client/lib/commands/HPEXPIREAT.spec.ts index f91bf967cf..7c369980bf 100644 --- a/packages/client/lib/commands/HPEXPIREAT.spec.ts +++ b/packages/client/lib/commands/HPEXPIREAT.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HPEXPIREAT from './HPEXPIREAT'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HPEXPIREAT', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,14 +10,14 @@ describe('HPEXPIREAT', () => { describe('transformArguments', () => { it('string + number', () => { assert.deepEqual( - HPEXPIREAT.transformArguments('key', 'field', 1), + parseArgs(HPEXPIREAT, 'key', 'field', 1), ['HPEXPIREAT', 'key', '1', 'FIELDS', '1', 'field'] ); }); it('array + number', () => { assert.deepEqual( - HPEXPIREAT.transformArguments('key', ['field1', 'field2'], 1), + parseArgs(HPEXPIREAT, 'key', ['field1', 'field2'], 1), ['HPEXPIREAT', 'key', '1', 'FIELDS', '2', 'field1', 'field2'] ); }); @@ -24,14 +25,14 @@ describe('HPEXPIREAT', () => { it('date', () => { const d = new Date(); assert.deepEqual( - HPEXPIREAT.transformArguments('key', ['field1'], d), + parseArgs(HPEXPIREAT, 'key', ['field1'], d), ['HPEXPIREAT', 'key', d.getTime().toString(), 'FIELDS', '1', 'field1'] ); }); it('with set option', () => { assert.deepEqual( - HPEXPIREAT.transformArguments('key', ['field1'], 1, 'XX'), + parseArgs(HPEXPIREAT, 'key', ['field1'], 1, 'XX'), ['HPEXPIREAT', 'key', '1', 'XX', 'FIELDS', '1', 'field1'] ); }); diff --git a/packages/client/lib/commands/HPEXPIREAT.ts b/packages/client/lib/commands/HPEXPIREAT.ts index a6250d9943..14288d7ae9 100644 --- a/packages/client/lib/commands/HPEXPIREAT.ts +++ b/packages/client/lib/commands/HPEXPIREAT.ts @@ -1,24 +1,28 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument, transformPXAT } from './generic-transformers'; +import { RedisVariadicArgument, transformPXAT } from './generic-transformers'; import { HashExpiration } from './HEXPIRE'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + IS_READ_ONLY: true, + parseCommand( + parser: CommandParser, key: RedisArgument, fields: RedisVariadicArgument, timestamp: number | Date, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['HPEXPIREAT', key, transformPXAT(timestamp)]; + parser.push('HPEXPIREAT'); + parser.pushKey(key); + parser.push(transformPXAT(timestamp)); if (mode) { - args.push(mode); + parser.push(mode); } - args.push('FIELDS') + parser.push('FIELDS') - return pushVariadicArgument(args, fields); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HPEXPIRETIME.spec.ts b/packages/client/lib/commands/HPEXPIRETIME.spec.ts index a66988c428..5673a725af 100644 --- a/packages/client/lib/commands/HPEXPIRETIME.spec.ts +++ b/packages/client/lib/commands/HPEXPIRETIME.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HPEXPIRETIME from './HPEXPIRETIME'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HPEXPIRETIME', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,14 +10,14 @@ describe('HPEXPIRETIME', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HPEXPIRETIME.transformArguments('key', 'field'), + parseArgs(HPEXPIRETIME, 'key', 'field'), ['HPEXPIRETIME', 'key', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HPEXPIRETIME.transformArguments('key', ['field1', 'field2']), + parseArgs(HPEXPIRETIME, 'key', ['field1', 'field2']), ['HPEXPIRETIME', 'key', 'FIELDS', '2', 'field1', 'field2'] ); }); diff --git a/packages/client/lib/commands/HPEXPIRETIME.ts b/packages/client/lib/commands/HPEXPIRETIME.ts index acdccf2511..cacce25a85 100644 --- a/packages/client/lib/commands/HPEXPIRETIME.ts +++ b/packages/client/lib/commands/HPEXPIRETIME.ts @@ -1,11 +1,18 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, NumberReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, fields: RedisVariadicArgument) { - return pushVariadicArgument(['HPEXPIRETIME', key, 'FIELDS'], fields); + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument, + ) { + parser.push('HPEXPIRETIME'); + parser.pushKey(key); + parser.push('FIELDS'); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HPTTL.spec.ts b/packages/client/lib/commands/HPTTL.spec.ts index 7280ef841c..baaa11b19c 100644 --- a/packages/client/lib/commands/HPTTL.spec.ts +++ b/packages/client/lib/commands/HPTTL.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HPTTL from './HPTTL'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HPTTL', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,14 +10,14 @@ describe('HPTTL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HPTTL.transformArguments('key', 'field'), + parseArgs(HPTTL, 'key', 'field'), ['HPTTL', 'key', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HPTTL.transformArguments('key', ['field1', 'field2']), + parseArgs(HPTTL, 'key', ['field1', 'field2']), ['HPTTL', 'key', 'FIELDS', '2', 'field1', 'field2'] ); }); diff --git a/packages/client/lib/commands/HPTTL.ts b/packages/client/lib/commands/HPTTL.ts index 4ab069db74..b9cd54a850 100644 --- a/packages/client/lib/commands/HPTTL.ts +++ b/packages/client/lib/commands/HPTTL.ts @@ -1,11 +1,18 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, NumberReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, fields: RedisVariadicArgument) { - return pushVariadicArgument(['HPTTL', key, 'FIELDS'], fields); + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument + ) { + parser.push('HPTTL'); + parser.pushKey(key); + parser.push('FIELDS'); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HRANDFIELD.spec.ts b/packages/client/lib/commands/HRANDFIELD.spec.ts index 33f2d28180..151636057a 100644 --- a/packages/client/lib/commands/HRANDFIELD.spec.ts +++ b/packages/client/lib/commands/HRANDFIELD.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HRANDFIELD from './HRANDFIELD'; +import { parseArgs } from './generic-transformers'; describe('HRANDFIELD', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - HRANDFIELD.transformArguments('key'), + parseArgs(HRANDFIELD, 'key'), ['HRANDFIELD', 'key'] ); }); diff --git a/packages/client/lib/commands/HRANDFIELD.ts b/packages/client/lib/commands/HRANDFIELD.ts index be878e244a..3383b94dcb 100644 --- a/packages/client/lib/commands/HRANDFIELD.ts +++ b/packages/client/lib/commands/HRANDFIELD.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['HRANDFIELD', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('HRANDFIELD'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts b/packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts index 99788dc496..ee3fc984d5 100644 --- a/packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts +++ b/packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HRANDFIELD_COUNT from './HRANDFIELD_COUNT'; +import { parseArgs } from './generic-transformers'; describe('HRANDFIELD COUNT', () => { testUtils.isVersionGreaterThanHook([6, 2, 5]); it('transformArguments', () => { assert.deepEqual( - HRANDFIELD_COUNT.transformArguments('key', 1), + parseArgs(HRANDFIELD_COUNT, 'key', 1), ['HRANDFIELD', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/HRANDFIELD_COUNT.ts b/packages/client/lib/commands/HRANDFIELD_COUNT.ts index 4b6f42a115..62abe97e35 100644 --- a/packages/client/lib/commands/HRANDFIELD_COUNT.ts +++ b/packages/client/lib/commands/HRANDFIELD_COUNT.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, count: number) { - return ['HRANDFIELD', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('HRANDFIELD'); + parser.pushKey(key); + parser.push(count.toString()); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts b/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts index ab36183c4a..aa8ebad1b9 100644 --- a/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts +++ b/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, UnwrapReply, Command } from '../RESP/types'; export type HRandFieldCountWithValuesReply = Array<{ @@ -6,10 +7,11 @@ export type HRandFieldCountWithValuesReply = Array<{ }>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, count: number) { - return ['HRANDFIELD', key, count.toString(), 'WITHVALUES']; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('HRANDFIELD'); + parser.pushKey(key); + parser.push(count.toString(), 'WITHVALUES'); }, transformReply: { 2: (rawReply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/HSCAN.spec.ts b/packages/client/lib/commands/HSCAN.spec.ts index a5f3cdca16..9e489f6190 100644 --- a/packages/client/lib/commands/HSCAN.spec.ts +++ b/packages/client/lib/commands/HSCAN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import HSCAN from './HSCAN'; describe('HSCAN', () => { describe('transformArguments', () => { it('cusror only', () => { assert.deepEqual( - HSCAN.transformArguments('key', '0'), + parseArgs(HSCAN, 'key', '0'), ['HSCAN', 'key', '0'] ); }); it('with MATCH', () => { assert.deepEqual( - HSCAN.transformArguments('key', '0', { + parseArgs(HSCAN, 'key', '0', { MATCH: 'pattern' }), ['HSCAN', 'key', '0', 'MATCH', 'pattern'] @@ -22,7 +23,7 @@ describe('HSCAN', () => { it('with COUNT', () => { assert.deepEqual( - HSCAN.transformArguments('key', '0', { + parseArgs(HSCAN, 'key', '0', { COUNT: 1 }), ['HSCAN', 'key', '0', 'COUNT', '1'] @@ -31,7 +32,7 @@ describe('HSCAN', () => { it('with MATCH & COUNT', () => { assert.deepEqual( - HSCAN.transformArguments('key', '0', { + parseArgs(HSCAN, 'key', '0', { MATCH: 'pattern', COUNT: 1 }), diff --git a/packages/client/lib/commands/HSCAN.ts b/packages/client/lib/commands/HSCAN.ts index db52db99fe..e1e40663a0 100644 --- a/packages/client/lib/commands/HSCAN.ts +++ b/packages/client/lib/commands/HSCAN.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; -import { ScanCommonOptions, pushScanArguments } from './SCAN'; +import { ScanCommonOptions, parseScanArguments } from './SCAN'; export interface HScanEntry { field: BlobStringReply; @@ -7,14 +8,16 @@ export interface HScanEntry { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, cursor: RedisArgument, options?: ScanCommonOptions ) { - return pushScanArguments(['HSCAN', key], cursor, options); + parser.push('HSCAN'); + parser.pushKey(key); + parseScanArguments(parser, cursor, options); }, transformReply([cursor, rawEntries]: [BlobStringReply, Array]) { const entries = []; diff --git a/packages/client/lib/commands/HSCAN_NOVALUES.spec.ts b/packages/client/lib/commands/HSCAN_NOVALUES.spec.ts index 1283a116dc..83a452a689 100644 --- a/packages/client/lib/commands/HSCAN_NOVALUES.spec.ts +++ b/packages/client/lib/commands/HSCAN_NOVALUES.spec.ts @@ -1,7 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HSCAN_NOVALUES from './HSCAN_NOVALUES'; -import { BlobStringReply } from '../RESP/types'; +import { parseArgs } from './generic-transformers'; describe('HSCAN_NOVALUES', () => { testUtils.isVersionGreaterThanHook([7,4]); @@ -9,14 +9,14 @@ describe('HSCAN_NOVALUES', () => { describe('transformArguments', () => { it('cusror only', () => { assert.deepEqual( - HSCAN_NOVALUES.transformArguments('key', '0'), + parseArgs(HSCAN_NOVALUES, 'key', '0'), ['HSCAN', 'key', '0', 'NOVALUES'] ); }); it('with MATCH', () => { assert.deepEqual( - HSCAN_NOVALUES.transformArguments('key', '0', { + parseArgs(HSCAN_NOVALUES, 'key', '0', { MATCH: 'pattern' }), ['HSCAN', 'key', '0', 'MATCH', 'pattern', 'NOVALUES'] @@ -25,7 +25,7 @@ describe('HSCAN_NOVALUES', () => { it('with COUNT', () => { assert.deepEqual( - HSCAN_NOVALUES.transformArguments('key', '0', { + parseArgs(HSCAN_NOVALUES, 'key', '0', { COUNT: 1 }), ['HSCAN', 'key', '0', 'COUNT', '1', 'NOVALUES'] @@ -34,7 +34,7 @@ describe('HSCAN_NOVALUES', () => { it('with MATCH & COUNT', () => { assert.deepEqual( - HSCAN_NOVALUES.transformArguments('key', '0', { + parseArgs(HSCAN_NOVALUES, 'key', '0', { MATCH: 'pattern', COUNT: 1 }), diff --git a/packages/client/lib/commands/HSCAN_NOVALUES.ts b/packages/client/lib/commands/HSCAN_NOVALUES.ts index 35ff861338..eff61a7aab 100644 --- a/packages/client/lib/commands/HSCAN_NOVALUES.ts +++ b/packages/client/lib/commands/HSCAN_NOVALUES.ts @@ -1,17 +1,13 @@ -import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; -import { ScanCommonOptions, pushScanArguments } from './SCAN'; +import { BlobStringReply, Command } from '../RESP/types'; +import HSCAN from './HSCAN'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - cursor: RedisArgument, - options?: ScanCommonOptions - ) { - const args = pushScanArguments(['HSCAN', key], cursor, options); - args.push('NOVALUES'); - return args; + parseCommand(...args: Parameters) { + const parser = args[0]; + + HSCAN.parseCommand(...args); + parser.push('NOVALUES'); }, transformReply([cursor, fields]: [BlobStringReply, Array]) { return { diff --git a/packages/client/lib/commands/HSET.spec.ts b/packages/client/lib/commands/HSET.spec.ts index eb5fdcd9b3..2cb53e6485 100644 --- a/packages/client/lib/commands/HSET.spec.ts +++ b/packages/client/lib/commands/HSET.spec.ts @@ -1,27 +1,28 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HSET from './HSET'; +import { parseArgs } from './generic-transformers'; describe('HSET', () => { describe('transformArguments', () => { describe('field, value', () => { it('string', () => { assert.deepEqual( - HSET.transformArguments('key', 'field', 'value'), + parseArgs(HSET, 'key', 'field', 'value'), ['HSET', 'key', 'field', 'value'] ); }); it('number', () => { assert.deepEqual( - HSET.transformArguments('key', 1, 2), + parseArgs(HSET, 'key', 1, 2), ['HSET', 'key', '1', '2'] ); }); it('Buffer', () => { assert.deepEqual( - HSET.transformArguments(Buffer.from('key'), Buffer.from('field'), Buffer.from('value')), + parseArgs(HSET, Buffer.from('key'), Buffer.from('field'), Buffer.from('value')), ['HSET', Buffer.from('key'), Buffer.from('field'), Buffer.from('value')] ); }); @@ -29,14 +30,14 @@ describe('HSET', () => { it('Map', () => { assert.deepEqual( - HSET.transformArguments('key', new Map([['field', 'value']])), + parseArgs(HSET, 'key', new Map([['field', 'value']])), ['HSET', 'key', 'field', 'value'] ); }); it('Array', () => { assert.deepEqual( - HSET.transformArguments('key', [['field', 'value']]), + parseArgs(HSET, 'key', [['field', 'value']]), ['HSET', 'key', 'field', 'value'] ); }); @@ -44,14 +45,14 @@ describe('HSET', () => { describe('Object', () => { it('string', () => { assert.deepEqual( - HSET.transformArguments('key', { field: 'value' }), + parseArgs(HSET, 'key', { field: 'value' }), ['HSET', 'key', 'field', 'value'] ); }); it('Buffer', () => { assert.deepEqual( - HSET.transformArguments('key', { field: Buffer.from('value') }), + parseArgs(HSET, 'key', { field: Buffer.from('value') }), ['HSET', 'key', 'field', Buffer.from('value')] ); }); diff --git a/packages/client/lib/commands/HSET.ts b/packages/client/lib/commands/HSET.ts index e14aa9d06f..1f50aeacf0 100644 --- a/packages/client/lib/commands/HSET.ts +++ b/packages/client/lib/commands/HSET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export type HashTypes = RedisArgument | number; @@ -17,51 +18,49 @@ type MultipleFieldsArguments = [...generic: GenericArguments, value: HSETObject export type HSETArguments = SingleFieldArguments | MultipleFieldsArguments; export default { - FIRST_KEY_INDEX: 1, - transformArguments(...[key, value, fieldValue]: SingleFieldArguments | MultipleFieldsArguments) { - const args: Array = ['HSET', key]; + parseCommand(parser: CommandParser, ...[key, value, fieldValue]: SingleFieldArguments | MultipleFieldsArguments) { + parser.push('HSET'); + parser.pushKey(key); if (typeof value === 'string' || typeof value === 'number' || value instanceof Buffer) { - args.push( + parser.push( convertValue(value), convertValue(fieldValue!) ); } else if (value instanceof Map) { - pushMap(args, value); + pushMap(parser, value); } else if (Array.isArray(value)) { - pushTuples(args, value); + pushTuples(parser, value); } else { - pushObject(args, value); + pushObject(parser, value); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; -function pushMap(args: Array, map: HSETMap): void { +function pushMap(parser: CommandParser, map: HSETMap): void { for (const [key, value] of map.entries()) { - args.push( + parser.push( convertValue(key), convertValue(value) ); } } -function pushTuples(args: Array, tuples: HSETTuples): void { +function pushTuples(parser: CommandParser, tuples: HSETTuples): void { for (const tuple of tuples) { if (Array.isArray(tuple)) { - pushTuples(args, tuple); + pushTuples(parser, tuple); continue; } - args.push(convertValue(tuple)); + parser.push(convertValue(tuple)); } } -function pushObject(args: Array, object: HSETObject): void { +function pushObject(parser: CommandParser, object: HSETObject): void { for (const key of Object.keys(object)) { - args.push( + parser.push( convertValue(key), convertValue(object[key]) ); diff --git a/packages/client/lib/commands/HSETNX.spec.ts b/packages/client/lib/commands/HSETNX.spec.ts index 522732624e..e65f9fb219 100644 --- a/packages/client/lib/commands/HSETNX.spec.ts +++ b/packages/client/lib/commands/HSETNX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HSETNX from './HSETNX'; +import { parseArgs } from './generic-transformers'; describe('HSETNX', () => { it('transformArguments', () => { assert.deepEqual( - HSETNX.transformArguments('key', 'field', 'value'), + parseArgs(HSETNX, 'key', 'field', 'value'), ['HSETNX', 'key', 'field', 'value'] ); }); diff --git a/packages/client/lib/commands/HSETNX.ts b/packages/client/lib/commands/HSETNX.ts index d26c42a76b..130d7cd81d 100644 --- a/packages/client/lib/commands/HSETNX.ts +++ b/packages/client/lib/commands/HSETNX.ts @@ -1,14 +1,17 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command, NumberReply } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, field: RedisArgument, value: RedisArgument ) { - return ['HSETNX', key, field, value]; + parser.push('HSETNX'); + parser.pushKey(key); + parser.push(field, value); }, transformReply: undefined as unknown as () => NumberReply<0 | 1> } as const satisfies Command; diff --git a/packages/client/lib/commands/HSTRLEN.spec.ts b/packages/client/lib/commands/HSTRLEN.spec.ts index 59b737b692..47dd0eaf79 100644 --- a/packages/client/lib/commands/HSTRLEN.spec.ts +++ b/packages/client/lib/commands/HSTRLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HSTRLEN from './HSTRLEN'; +import { parseArgs } from './generic-transformers'; describe('HSTRLEN', () => { it('transformArguments', () => { assert.deepEqual( - HSTRLEN.transformArguments('key', 'field'), + parseArgs(HSTRLEN, 'key', 'field'), ['HSTRLEN', 'key', 'field'] ); }); diff --git a/packages/client/lib/commands/HSTRLEN.ts b/packages/client/lib/commands/HSTRLEN.ts index 843c4baf7e..2468747d4c 100644 --- a/packages/client/lib/commands/HSTRLEN.ts +++ b/packages/client/lib/commands/HSTRLEN.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, field: RedisArgument) { - return ['HSTRLEN', key, field]; + parseCommand(parser: CommandParser, key: RedisArgument, field: RedisArgument) { + parser.push('HSTRLEN'); + parser.pushKey(key); + parser.push(field); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HTTL.spec.ts b/packages/client/lib/commands/HTTL.spec.ts index df74c8a728..a79500e4d0 100644 --- a/packages/client/lib/commands/HTTL.spec.ts +++ b/packages/client/lib/commands/HTTL.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HTTL from './HTTL'; import { HASH_EXPIRATION_TIME } from './HEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('HTTL', () => { testUtils.isVersionGreaterThanHook([7, 4]); @@ -9,18 +10,17 @@ describe('HTTL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - HTTL.transformArguments('key', 'field'), + parseArgs(HTTL, 'key', 'field'), ['HTTL', 'key', 'FIELDS', '1', 'field'] ); }); it('array', () => { assert.deepEqual( - HTTL.transformArguments('key', ['field1', 'field2']), + parseArgs(HTTL, 'key', ['field1', 'field2']), ['HTTL', 'key', 'FIELDS', '2', 'field1', 'field2'] ); }); - }); testUtils.testWithClient('hTTL', async client => { diff --git a/packages/client/lib/commands/HTTL.ts b/packages/client/lib/commands/HTTL.ts index 66b50ff3e6..4b8fe5d7e8 100644 --- a/packages/client/lib/commands/HTTL.ts +++ b/packages/client/lib/commands/HTTL.ts @@ -1,11 +1,18 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, Command, NullReply, NumberReply, RedisArgument } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, fields: RedisVariadicArgument) { - return pushVariadicArgument(['HTTL', key, 'FIELDS'], fields); + parseCommand( + parser: CommandParser, + key: RedisArgument, + fields: RedisVariadicArgument + ) { + parser.push('HTTL'); + parser.pushKey(key); + parser.push('FIELDS'); + parser.pushVariadicWithLength(fields); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/HVALS.spec.ts b/packages/client/lib/commands/HVALS.spec.ts index 922aa58813..89cbb52861 100644 --- a/packages/client/lib/commands/HVALS.spec.ts +++ b/packages/client/lib/commands/HVALS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import HVALS from './HVALS'; +import { parseArgs } from './generic-transformers'; describe('HVALS', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - HVALS.transformArguments('key'), + parseArgs(HVALS, 'key'), ['HVALS', 'key'] ); }); diff --git a/packages/client/lib/commands/HVALS.ts b/packages/client/lib/commands/HVALS.ts index ee4193f5ce..ab17e47f53 100644 --- a/packages/client/lib/commands/HVALS.ts +++ b/packages/client/lib/commands/HVALS.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['HVALS', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('HVALS'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/INCR.spec.ts b/packages/client/lib/commands/INCR.spec.ts index 6712976024..0fe7ed7f8e 100644 --- a/packages/client/lib/commands/INCR.spec.ts +++ b/packages/client/lib/commands/INCR.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INCR from './INCR'; +import { parseArgs } from './generic-transformers'; describe('INCR', () => { it('transformArguments', () => { assert.deepEqual( - INCR.transformArguments('key'), + parseArgs(INCR, 'key'), ['INCR', 'key'] ); }); diff --git a/packages/client/lib/commands/INCR.ts b/packages/client/lib/commands/INCR.ts index eb38256c9d..e719f06bc1 100644 --- a/packages/client/lib/commands/INCR.ts +++ b/packages/client/lib/commands/INCR.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument) { - return ['INCR', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('INCR'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/INCRBY.spec.ts b/packages/client/lib/commands/INCRBY.spec.ts index d66c01acce..e2a5842f20 100644 --- a/packages/client/lib/commands/INCRBY.spec.ts +++ b/packages/client/lib/commands/INCRBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INCRBY from './INCRBY'; +import { parseArgs } from './generic-transformers'; describe('INCRBY', () => { it('transformArguments', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1), + parseArgs(INCRBY, 'key', 1), ['INCRBY', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/INCRBY.ts b/packages/client/lib/commands/INCRBY.ts index 5e94348fe6..bf46318504 100644 --- a/packages/client/lib/commands/INCRBY.ts +++ b/packages/client/lib/commands/INCRBY.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, increment: number) { - return ['INCRBY', key, increment.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, increment: number) { + parser.push('INCRBY'); + parser.pushKey(key); + parser.push(increment.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/INCRBYFLOAT.spec.ts b/packages/client/lib/commands/INCRBYFLOAT.spec.ts index 8bdd9c332d..5759697070 100644 --- a/packages/client/lib/commands/INCRBYFLOAT.spec.ts +++ b/packages/client/lib/commands/INCRBYFLOAT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INCRBYFLOAT from './INCRBYFLOAT'; +import { parseArgs } from './generic-transformers'; describe('INCRBYFLOAT', () => { it('transformArguments', () => { assert.deepEqual( - INCRBYFLOAT.transformArguments('key', 1.5), + parseArgs(INCRBYFLOAT, 'key', 1.5), ['INCRBYFLOAT', 'key', '1.5'] ); }); diff --git a/packages/client/lib/commands/INCRBYFLOAT.ts b/packages/client/lib/commands/INCRBYFLOAT.ts index 16f59e68c1..9a2dba42a6 100644 --- a/packages/client/lib/commands/INCRBYFLOAT.ts +++ b/packages/client/lib/commands/INCRBYFLOAT.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, increment: number) { - return ['INCRBYFLOAT', key, increment.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, increment: number) { + parser.push('INCRBYFLOAT'); + parser.pushKey(key); + parser.push(increment.toString()); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/INFO.spec.ts b/packages/client/lib/commands/INFO.spec.ts index c455577872..7ee8a95c13 100644 --- a/packages/client/lib/commands/INFO.spec.ts +++ b/packages/client/lib/commands/INFO.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INFO from './INFO'; +import { parseArgs } from './generic-transformers'; describe('INFO', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - INFO.transformArguments(), + parseArgs(INFO), ['INFO'] ); }); it('server section', () => { assert.deepEqual( - INFO.transformArguments('server'), + parseArgs(INFO, 'server'), ['INFO', 'server'] ); }); diff --git a/packages/client/lib/commands/INFO.ts b/packages/client/lib/commands/INFO.ts index 9877c0cf66..82cbd497a5 100644 --- a/packages/client/lib/commands/INFO.ts +++ b/packages/client/lib/commands/INFO.ts @@ -1,16 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, VerbatimStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(section?: RedisArgument) { - const args: Array = ['INFO']; + parseCommand(parser: CommandParser, section?: RedisArgument) { + parser.push('INFO'); if (section) { - args.push(section); + parser.push(section); } - - return args; }, transformReply: undefined as unknown as () => VerbatimStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/KEYS.ts b/packages/client/lib/commands/KEYS.ts index 488ba1154c..e516245d2e 100644 --- a/packages/client/lib/commands/KEYS.ts +++ b/packages/client/lib/commands/KEYS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(pattern: RedisArgument) { - return ['KEYS', pattern]; + parseCommand(parser: CommandParser, pattern: RedisArgument) { + parser.push('KEYS', pattern); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LASTSAVE.spec.ts b/packages/client/lib/commands/LASTSAVE.spec.ts index 74cf30705f..fba2681117 100644 --- a/packages/client/lib/commands/LASTSAVE.spec.ts +++ b/packages/client/lib/commands/LASTSAVE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LASTSAVE from './LASTSAVE'; +import { parseArgs } from './generic-transformers'; describe('LASTSAVE', () => { it('transformArguments', () => { assert.deepEqual( - LASTSAVE.transformArguments(), + parseArgs(LASTSAVE), ['LASTSAVE'] ); }); diff --git a/packages/client/lib/commands/LASTSAVE.ts b/packages/client/lib/commands/LASTSAVE.ts index a65161f78b..447cb95ab6 100644 --- a/packages/client/lib/commands/LASTSAVE.ts +++ b/packages/client/lib/commands/LASTSAVE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['LASTSAVE']; + parseCommand(parser: CommandParser) { + parser.push('LASTSAVE'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LATENCY_DOCTOR.spec.ts b/packages/client/lib/commands/LATENCY_DOCTOR.spec.ts index 00eabfb4cb..654751b5b5 100644 --- a/packages/client/lib/commands/LATENCY_DOCTOR.spec.ts +++ b/packages/client/lib/commands/LATENCY_DOCTOR.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LATENCY_DOCTOR from './LATENCY_DOCTOR'; +import { parseArgs } from './generic-transformers'; describe('LATENCY DOCTOR', () => { it('transformArguments', () => { assert.deepEqual( - LATENCY_DOCTOR.transformArguments(), + parseArgs(LATENCY_DOCTOR), ['LATENCY', 'DOCTOR'] ); }); diff --git a/packages/client/lib/commands/LATENCY_DOCTOR.ts b/packages/client/lib/commands/LATENCY_DOCTOR.ts index 96dc6b6570..49c830b306 100644 --- a/packages/client/lib/commands/LATENCY_DOCTOR.ts +++ b/packages/client/lib/commands/LATENCY_DOCTOR.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['LATENCY', 'DOCTOR']; + parseCommand(parser: CommandParser) { + parser.push('LATENCY', 'DOCTOR'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LATENCY_GRAPH.spec.ts b/packages/client/lib/commands/LATENCY_GRAPH.spec.ts index 03ad8e2c88..7135dc1c42 100644 --- a/packages/client/lib/commands/LATENCY_GRAPH.spec.ts +++ b/packages/client/lib/commands/LATENCY_GRAPH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LATENCY_GRAPH from './LATENCY_GRAPH'; +import { parseArgs } from './generic-transformers'; describe('LATENCY GRAPH', () => { it('transformArguments', () => { assert.deepEqual( - LATENCY_GRAPH.transformArguments('command'), + parseArgs(LATENCY_GRAPH, 'command'), [ 'LATENCY', 'GRAPH', diff --git a/packages/client/lib/commands/LATENCY_GRAPH.ts b/packages/client/lib/commands/LATENCY_GRAPH.ts index 7d5f54288b..20251c3cde 100644 --- a/packages/client/lib/commands/LATENCY_GRAPH.ts +++ b/packages/client/lib/commands/LATENCY_GRAPH.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export const LATENCY_EVENTS = { @@ -22,10 +23,10 @@ export const LATENCY_EVENTS = { export type LatencyEvent = typeof LATENCY_EVENTS[keyof typeof LATENCY_EVENTS]; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(event: LatencyEvent) { - return ['LATENCY', 'GRAPH', event]; + parseCommand(parser: CommandParser, event: LatencyEvent) { + parser.push('LATENCY', 'GRAPH', event); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LATENCY_HISTORY.spec.ts b/packages/client/lib/commands/LATENCY_HISTORY.spec.ts index 509c856e28..64f94d0d1a 100644 --- a/packages/client/lib/commands/LATENCY_HISTORY.spec.ts +++ b/packages/client/lib/commands/LATENCY_HISTORY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import LATENCY_HISTORY from './LATENCY_HISTORY'; +import { parseArgs } from './generic-transformers'; describe('LATENCY HISTORY', () => { it('transformArguments', () => { assert.deepEqual( - LATENCY_HISTORY.transformArguments('command'), + parseArgs(LATENCY_HISTORY, 'command'), ['LATENCY', 'HISTORY', 'command'] ); }); diff --git a/packages/client/lib/commands/LATENCY_HISTORY.ts b/packages/client/lib/commands/LATENCY_HISTORY.ts index df5b1772b2..6e0e4d5c56 100644 --- a/packages/client/lib/commands/LATENCY_HISTORY.ts +++ b/packages/client/lib/commands/LATENCY_HISTORY.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, TuplesReply, NumberReply, Command } from '../RESP/types'; export type LatencyEventType = ( @@ -20,10 +21,10 @@ export type LatencyEventType = ( ); export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(event: LatencyEventType) { - return ['LATENCY', 'HISTORY', event]; + parseCommand(parser: CommandParser, event: LatencyEventType) { + parser.push('LATENCY', 'HISTORY', event); }, transformReply: undefined as unknown as () => ArrayReply { it('transformArguments', () => { assert.deepEqual( - LATENCY_LATEST.transformArguments(), + parseArgs(LATENCY_LATEST), ['LATENCY', 'LATEST'] ); }); diff --git a/packages/client/lib/commands/LATENCY_LATEST.ts b/packages/client/lib/commands/LATENCY_LATEST.ts index 29548af30d..2ce3efd291 100644 --- a/packages/client/lib/commands/LATENCY_LATEST.ts +++ b/packages/client/lib/commands/LATENCY_LATEST.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['LATENCY', 'LATEST']; + parseCommand(parser: CommandParser) { + parser.push('LATENCY', 'LATEST'); }, transformReply: undefined as unknown as () => ArrayReply<[ name: BlobStringReply, diff --git a/packages/client/lib/commands/LCS.spec.ts b/packages/client/lib/commands/LCS.spec.ts index ff9d63db1b..aedbb1b34e 100644 --- a/packages/client/lib/commands/LCS.spec.ts +++ b/packages/client/lib/commands/LCS.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LCS from './LCS'; +import { parseArgs } from './generic-transformers'; describe('LCS', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - LCS.transformArguments('1', '2'), + parseArgs(LCS, '1', '2'), ['LCS', '1', '2'] ); }); diff --git a/packages/client/lib/commands/LCS.ts b/packages/client/lib/commands/LCS.ts index b798f12aa3..ed4f11ad99 100644 --- a/packages/client/lib/commands/LCS.ts +++ b/packages/client/lib/commands/LCS.ts @@ -1,13 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key1: RedisArgument, key2: RedisArgument ) { - return ['LCS', key1, key2]; + parser.push('LCS'); + parser.pushKeys([key1, key2]); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LCS_IDX.spec.ts b/packages/client/lib/commands/LCS_IDX.spec.ts index 2f60a205fa..c4cc6681d8 100644 --- a/packages/client/lib/commands/LCS_IDX.spec.ts +++ b/packages/client/lib/commands/LCS_IDX.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LCS_IDX from './LCS_IDX'; +import { parseArgs } from './generic-transformers'; describe('LCS IDX', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - LCS_IDX.transformArguments('1', '2'), + parseArgs(LCS_IDX, '1', '2'), ['LCS', '1', '2', 'IDX'] ); }); diff --git a/packages/client/lib/commands/LCS_IDX.ts b/packages/client/lib/commands/LCS_IDX.ts index 0c266fffe1..cb0a6b0765 100644 --- a/packages/client/lib/commands/LCS_IDX.ts +++ b/packages/client/lib/commands/LCS_IDX.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NumberReply, UnwrapReply, Resp2Reply, Command, TuplesReply } from '../RESP/types'; import LCS from './LCS'; @@ -23,22 +24,20 @@ export type LcsIdxReply = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: LCS.FIRST_KEY_INDEX, IS_READ_ONLY: LCS.IS_READ_ONLY, - transformArguments( + parseCommand( + parser: CommandParser, key1: RedisArgument, key2: RedisArgument, options?: LcsIdxOptions ) { - const args = LCS.transformArguments(key1, key2); + LCS.parseCommand(parser, key1, key2); - args.push('IDX'); + parser.push('IDX'); if (options?.MINMATCHLEN) { - args.push('MINMATCHLEN', options.MINMATCHLEN.toString()); + parser.push('MINMATCHLEN', options.MINMATCHLEN.toString()); } - - return args; }, transformReply: { 2: (reply: UnwrapReply>) => ({ diff --git a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts index 39ba17e8f2..92ecad4761 100644 --- a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts +++ b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LCS_IDX_WITHMATCHLEN from './LCS_IDX_WITHMATCHLEN'; +import { parseArgs } from './generic-transformers'; describe('LCS IDX WITHMATCHLEN', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - LCS_IDX_WITHMATCHLEN.transformArguments('1', '2'), + parseArgs(LCS_IDX_WITHMATCHLEN, '1', '2'), ['LCS', '1', '2', 'IDX', 'WITHMATCHLEN'] ); }); diff --git a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts index 4e64585203..d2a743983e 100644 --- a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts +++ b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts @@ -1,5 +1,5 @@ -import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, TuplesReply, NumberReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; -import LCS_IDX, { LcsIdxOptions, LcsIdxRange } from './LCS_IDX'; +import { TuplesToMapReply, BlobStringReply, ArrayReply, TuplesReply, NumberReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; +import LCS_IDX, { LcsIdxRange } from './LCS_IDX'; export type LcsIdxWithMatchLenMatches = ArrayReply< TuplesReply<[ @@ -15,16 +15,11 @@ export type LcsIdxWithMatchLenReply = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: LCS_IDX.FIRST_KEY_INDEX, IS_READ_ONLY: LCS_IDX.IS_READ_ONLY, - transformArguments( - key1: RedisArgument, - key2: RedisArgument, - options?: LcsIdxOptions - ) { - const args = LCS_IDX.transformArguments(key1, key2); - args.push('WITHMATCHLEN'); - return args; + parseCommand(...args: Parameters) { + const parser = args[0]; + LCS_IDX.parseCommand(...args); + parser.push('WITHMATCHLEN'); }, transformReply: { 2: (reply: UnwrapReply>) => ({ diff --git a/packages/client/lib/commands/LCS_LEN.spec.ts b/packages/client/lib/commands/LCS_LEN.spec.ts index 9dc163a68a..53a2e83c32 100644 --- a/packages/client/lib/commands/LCS_LEN.spec.ts +++ b/packages/client/lib/commands/LCS_LEN.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LCS_LEN from './LCS_LEN'; +import { parseArgs } from './generic-transformers'; describe('LCS_LEN', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - LCS_LEN.transformArguments('1', '2'), + parseArgs(LCS_LEN, '1', '2'), ['LCS', '1', '2', 'LEN'] ); }); diff --git a/packages/client/lib/commands/LCS_LEN.ts b/packages/client/lib/commands/LCS_LEN.ts index d5d0e77e4d..a1f92d914a 100644 --- a/packages/client/lib/commands/LCS_LEN.ts +++ b/packages/client/lib/commands/LCS_LEN.ts @@ -1,16 +1,13 @@ -import { RedisArgument, NumberReply, Command } from '../RESP/types'; +import { NumberReply, Command } from '../RESP/types'; import LCS from './LCS'; export default { - FIRST_KEY_INDEX: LCS.FIRST_KEY_INDEX, IS_READ_ONLY: LCS.IS_READ_ONLY, - transformArguments( - key1: RedisArgument, - key2: RedisArgument - ) { - const args = LCS.transformArguments(key1, key2); - args.push('LEN'); - return args; + parseCommand(...args: Parameters) { + const parser = args[0]; + + LCS.parseCommand(...args); + parser.push('LEN'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LINDEX.spec.ts b/packages/client/lib/commands/LINDEX.spec.ts index 60346b85f2..41eff474a1 100644 --- a/packages/client/lib/commands/LINDEX.spec.ts +++ b/packages/client/lib/commands/LINDEX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LINDEX from './LINDEX'; +import { parseArgs } from './generic-transformers'; describe('LINDEX', () => { it('transformArguments', () => { assert.deepEqual( - LINDEX.transformArguments('key', 0), + parseArgs(LINDEX, 'key', 0), ['LINDEX', 'key', '0'] ); }); diff --git a/packages/client/lib/commands/LINDEX.ts b/packages/client/lib/commands/LINDEX.ts index 0478bf9dc4..6335fc40c2 100644 --- a/packages/client/lib/commands/LINDEX.ts +++ b/packages/client/lib/commands/LINDEX.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, index: number) { - return ['LINDEX', key, index.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, index: number) { + parser.push('LINDEX'); + parser.pushKey(key); + parser.push(index.toString()); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LINSERT.spec.ts b/packages/client/lib/commands/LINSERT.spec.ts index 6cafa3f5a8..c3c89d56c1 100644 --- a/packages/client/lib/commands/LINSERT.spec.ts +++ b/packages/client/lib/commands/LINSERT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LINSERT from './LINSERT'; +import { parseArgs } from './generic-transformers'; describe('LINSERT', () => { it('transformArguments', () => { assert.deepEqual( - LINSERT.transformArguments('key', 'BEFORE', 'pivot', 'element'), + parseArgs(LINSERT, 'key', 'BEFORE', 'pivot', 'element'), ['LINSERT', 'key', 'BEFORE', 'pivot', 'element'] ); }); diff --git a/packages/client/lib/commands/LINSERT.ts b/packages/client/lib/commands/LINSERT.ts index 4bdc77de5a..8a40ac6663 100644 --- a/packages/client/lib/commands/LINSERT.ts +++ b/packages/client/lib/commands/LINSERT.ts @@ -1,23 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; type LInsertPosition = 'BEFORE' | 'AFTER'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, position: LInsertPosition, pivot: RedisArgument, element: RedisArgument ) { - return [ - 'LINSERT', - key, - position, - pivot, - element - ]; + parser.push('LINSERT'); + parser.pushKey(key); + parser.push(position, pivot, element); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LLEN.spec.ts b/packages/client/lib/commands/LLEN.spec.ts index f6ac9a73cc..d86078d0b4 100644 --- a/packages/client/lib/commands/LLEN.spec.ts +++ b/packages/client/lib/commands/LLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LLEN from './LLEN'; +import { parseArgs } from './generic-transformers'; describe('LLEN', () => { it('transformArguments', () => { assert.deepEqual( - LLEN.transformArguments('key'), + parseArgs(LLEN, 'key'), ['LLEN', 'key'] ); }); diff --git a/packages/client/lib/commands/LLEN.ts b/packages/client/lib/commands/LLEN.ts index dda59ddf29..674e022e60 100644 --- a/packages/client/lib/commands/LLEN.ts +++ b/packages/client/lib/commands/LLEN.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['LLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('LLEN'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LMOVE.spec.ts b/packages/client/lib/commands/LMOVE.spec.ts index 86740aa7b7..bed3ff8eab 100644 --- a/packages/client/lib/commands/LMOVE.spec.ts +++ b/packages/client/lib/commands/LMOVE.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LMOVE from './LMOVE'; +import { parseArgs } from './generic-transformers'; describe('LMOVE', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - LMOVE.transformArguments('source', 'destination', 'LEFT', 'RIGHT'), + parseArgs(LMOVE, 'source', 'destination', 'LEFT', 'RIGHT'), ['LMOVE', 'source', 'destination', 'LEFT', 'RIGHT'] ); }); diff --git a/packages/client/lib/commands/LMOVE.ts b/packages/client/lib/commands/LMOVE.ts index 95adc71a0f..f3ac847e90 100644 --- a/packages/client/lib/commands/LMOVE.ts +++ b/packages/client/lib/commands/LMOVE.ts @@ -1,22 +1,19 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; import { ListSide } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, source: RedisArgument, destination: RedisArgument, sourceSide: ListSide, destinationSide: ListSide ) { - return [ - 'LMOVE', - source, - destination, - sourceSide, - destinationSide, - ]; + parser.push('LMOVE'); + parser.pushKeys([source, destination]); + parser.push(sourceSide, destinationSide); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LMPOP.spec.ts b/packages/client/lib/commands/LMPOP.spec.ts index faf39e053e..bd2cf869e7 100644 --- a/packages/client/lib/commands/LMPOP.spec.ts +++ b/packages/client/lib/commands/LMPOP.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LMPOP from './LMPOP'; +import { parseArgs } from './generic-transformers'; describe('LMPOP', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('LMPOP', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - LMPOP.transformArguments('key', 'LEFT'), + parseArgs(LMPOP, 'key', 'LEFT'), ['LMPOP', '1', 'key', 'LEFT'] ); }); it('with COUNT', () => { assert.deepEqual( - LMPOP.transformArguments('key', 'LEFT', { + parseArgs(LMPOP, 'key', 'LEFT', { COUNT: 2 }), ['LMPOP', '1', 'key', 'LEFT', 'COUNT', '2'] diff --git a/packages/client/lib/commands/LMPOP.ts b/packages/client/lib/commands/LMPOP.ts index 49f7272ec4..c8095e42e7 100644 --- a/packages/client/lib/commands/LMPOP.ts +++ b/packages/client/lib/commands/LMPOP.ts @@ -1,34 +1,32 @@ -import { CommandArguments, NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types'; -import { ListSide, RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; +import { CommandParser } from '../client/parser'; +import { NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types'; +import { ListSide, RedisVariadicArgument, Tail } from './generic-transformers'; export interface LMPopOptions { COUNT?: number; } -export function transformLMPopArguments( - args: CommandArguments, +export function parseLMPopArguments( + parser: CommandParser, keys: RedisVariadicArgument, side: ListSide, options?: LMPopOptions -): CommandArguments { - args = pushVariadicArgument(args, keys); - - args.push(side); +) { + parser.pushKeysLength(keys); + parser.push(side); if (options?.COUNT !== undefined) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } - - return args; } -export type LMPopArguments = typeof transformLMPopArguments extends (_: any, ...args: infer T) => any ? T : never; +export type LMPopArguments = Tail>; export default { - FIRST_KEY_INDEX: 2, - IS_READ_ONLY: false, - transformArguments(...args: LMPopArguments) { - return transformLMPopArguments(['LMPOP'], ...args); + IS_READ_ONLY: false, + parseCommand(parser: CommandParser, ...args: LMPopArguments) { + parser.push('LMPOP'); + parseLMPopArguments(parser, ...args); }, transformReply: undefined as unknown as () => NullReply | TuplesReply<[ key: BlobStringReply, diff --git a/packages/client/lib/commands/LOLWUT.spec.ts b/packages/client/lib/commands/LOLWUT.spec.ts index b05c4168f6..b06030b0d0 100644 --- a/packages/client/lib/commands/LOLWUT.spec.ts +++ b/packages/client/lib/commands/LOLWUT.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LOLWUT from './LOLWUT'; +import { parseArgs } from './generic-transformers'; describe('LOLWUT', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - LOLWUT.transformArguments(), + parseArgs(LOLWUT), ['LOLWUT'] ); }); it('with version', () => { assert.deepEqual( - LOLWUT.transformArguments(5), + parseArgs(LOLWUT, 5), ['LOLWUT', 'VERSION', '5'] ); }); it('with version and optional arguments', () => { assert.deepEqual( - LOLWUT.transformArguments(5, 1, 2, 3), + parseArgs(LOLWUT, 5, 1, 2, 3), ['LOLWUT', 'VERSION', '5', '1', '2', '3'] ); }); diff --git a/packages/client/lib/commands/LOLWUT.ts b/packages/client/lib/commands/LOLWUT.ts index 7a6c8329d6..372bf53696 100644 --- a/packages/client/lib/commands/LOLWUT.ts +++ b/packages/client/lib/commands/LOLWUT.ts @@ -1,20 +1,18 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(version?: number, ...optionalArguments: Array) { - const args = ['LOLWUT']; - + parseCommand(parser: CommandParser, version?: number, ...optionalArguments: Array) { + parser.push('LOLWUT'); if (version) { - args.push( + parser.push( 'VERSION', - version.toString(), - ...optionalArguments.map(String), + version.toString() ); + parser.pushVariadic(optionalArguments.map(String)); } - - return args; }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPOP.spec.ts b/packages/client/lib/commands/LPOP.spec.ts index 944e559b15..93449bdbf5 100644 --- a/packages/client/lib/commands/LPOP.spec.ts +++ b/packages/client/lib/commands/LPOP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPOP from './LPOP'; +import { parseArgs } from './generic-transformers'; describe('LPOP', () => { it('transformArguments', () => { assert.deepEqual( - LPOP.transformArguments('key'), + parseArgs(LPOP, 'key'), ['LPOP', 'key'] ); }); diff --git a/packages/client/lib/commands/LPOP.ts b/packages/client/lib/commands/LPOP.ts index 7c85c30f9a..3125236bfa 100644 --- a/packages/client/lib/commands/LPOP.ts +++ b/packages/client/lib/commands/LPOP.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument) { - return ['LPOP', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('LPOP'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPOP_COUNT.spec.ts b/packages/client/lib/commands/LPOP_COUNT.spec.ts index 8286a50442..04bb3648d0 100644 --- a/packages/client/lib/commands/LPOP_COUNT.spec.ts +++ b/packages/client/lib/commands/LPOP_COUNT.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPOP_COUNT from './LPOP_COUNT'; +import { parseArgs } from './generic-transformers'; describe('LPOP COUNT', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - LPOP_COUNT.transformArguments('key', 1), + parseArgs(LPOP_COUNT, 'key', 1), ['LPOP', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/LPOP_COUNT.ts b/packages/client/lib/commands/LPOP_COUNT.ts index a1536e78dc..6d9aba42c2 100644 --- a/packages/client/lib/commands/LPOP_COUNT.ts +++ b/packages/client/lib/commands/LPOP_COUNT.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NullReply, ArrayReply, BlobStringReply, Command } from '../RESP/types'; +import LPOP from './LPOP'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, count: number) { - return ['LPOP', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + LPOP.parseCommand(parser, key); + parser.push(count.toString()) }, transformReply: undefined as unknown as () => NullReply | ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPOS.spec.ts b/packages/client/lib/commands/LPOS.spec.ts index 94c0bb3c03..f26af3f540 100644 --- a/packages/client/lib/commands/LPOS.spec.ts +++ b/packages/client/lib/commands/LPOS.spec.ts @@ -1,21 +1,22 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPOS from './LPOS'; +import { parseArgs } from './generic-transformers'; describe('LPOS', () => { testUtils.isVersionGreaterThanHook([6, 0, 6]); - describe('transformArguments', () => { + describe('processCommand', () => { it('simple', () => { assert.deepEqual( - LPOS.transformArguments('key', 'element'), + parseArgs(LPOS, 'key', 'element'), ['LPOS', 'key', 'element'] ); }); it('with RANK', () => { assert.deepEqual( - LPOS.transformArguments('key', 'element', { + parseArgs(LPOS, 'key', 'element', { RANK: 0 }), ['LPOS', 'key', 'element', 'RANK', '0'] @@ -24,7 +25,7 @@ describe('LPOS', () => { it('with MAXLEN', () => { assert.deepEqual( - LPOS.transformArguments('key', 'element', { + parseArgs(LPOS, 'key', 'element', { MAXLEN: 10 }), ['LPOS', 'key', 'element', 'MAXLEN', '10'] @@ -33,7 +34,7 @@ describe('LPOS', () => { it('with RANK, MAXLEN', () => { assert.deepEqual( - LPOS.transformArguments('key', 'element', { + parseArgs(LPOS, 'key', 'element', { RANK: 0, MAXLEN: 10 }), diff --git a/packages/client/lib/commands/LPOS.ts b/packages/client/lib/commands/LPOS.ts index 047d80d7c2..bb05ba6555 100644 --- a/packages/client/lib/commands/LPOS.ts +++ b/packages/client/lib/commands/LPOS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, NullReply, Command } from '../RESP/types'; export interface LPosOptions { @@ -6,26 +7,25 @@ export interface LPosOptions { } export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, element: RedisArgument, options?: LPosOptions ) { - const args = ['LPOS', key, element]; + parser.push('LPOS'); + parser.pushKey(key); + parser.push(element); - if (options) { - if (typeof options.RANK === 'number') { - args.push('RANK', options.RANK.toString()); - } - - if (typeof options.MAXLEN === 'number') { - args.push('MAXLEN', options.MAXLEN.toString()); - } + if (options?.RANK !== undefined) { + parser.push('RANK', options.RANK.toString()); } - return args; + if (options?.MAXLEN !== undefined) { + parser.push('MAXLEN', options.MAXLEN.toString()); + } }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPOS_COUNT.spec.ts b/packages/client/lib/commands/LPOS_COUNT.spec.ts index 747ffbc01c..702ef5a746 100644 --- a/packages/client/lib/commands/LPOS_COUNT.spec.ts +++ b/packages/client/lib/commands/LPOS_COUNT.spec.ts @@ -1,21 +1,22 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPOS_COUNT from './LPOS_COUNT'; +import { parseArgs } from './generic-transformers'; describe('LPOS COUNT', () => { testUtils.isVersionGreaterThanHook([6, 0, 6]); - describe('transformArguments', () => { + describe('processCommand', () => { it('simple', () => { assert.deepEqual( - LPOS_COUNT.transformArguments('key', 'element', 0), + parseArgs(LPOS_COUNT, 'key', 'element', 0), ['LPOS', 'key', 'element', 'COUNT', '0'] ); }); it('with RANK', () => { assert.deepEqual( - LPOS_COUNT.transformArguments('key', 'element', 0, { + parseArgs(LPOS_COUNT, 'key', 'element', 0, { RANK: 0 }), ['LPOS', 'key', 'element', 'RANK', '0', 'COUNT', '0'] @@ -24,20 +25,20 @@ describe('LPOS COUNT', () => { it('with MAXLEN', () => { assert.deepEqual( - LPOS_COUNT.transformArguments('key', 'element', 0, { + parseArgs(LPOS_COUNT, 'key', 'element', 0, { MAXLEN: 10 }), - ['LPOS', 'key', 'element', 'COUNT', '0', 'MAXLEN', '10'] + ['LPOS', 'key', 'element', 'MAXLEN', '10', 'COUNT', '0'] ); }); it('with RANK, MAXLEN', () => { assert.deepEqual( - LPOS_COUNT.transformArguments('key', 'element', 0, { + parseArgs(LPOS_COUNT, 'key', 'element', 0, { RANK: 0, MAXLEN: 10 }), - ['LPOS', 'key', 'element', 'RANK', '0', 'COUNT', '0', 'MAXLEN', '10'] + ['LPOS', 'key', 'element', 'RANK', '0', 'MAXLEN', '10', 'COUNT', '0'] ); }); }); diff --git a/packages/client/lib/commands/LPOS_COUNT.ts b/packages/client/lib/commands/LPOS_COUNT.ts index 1b057cff1f..e782a2d26e 100644 --- a/packages/client/lib/commands/LPOS_COUNT.ts +++ b/packages/client/lib/commands/LPOS_COUNT.ts @@ -1,28 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NumberReply, Command } from '../RESP/types'; import LPOS, { LPosOptions } from './LPOS'; export default { - FIRST_KEY_INDEX: LPOS.FIRST_KEY_INDEX, + CACHEABLE: LPOS.CACHEABLE, IS_READ_ONLY: LPOS.IS_READ_ONLY, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, element: RedisArgument, count: number, options?: LPosOptions ) { - const args = ['LPOS', key, element]; + LPOS.parseCommand(parser, key, element, options); - if (options?.RANK !== undefined) { - args.push('RANK', options.RANK.toString()); - } - - args.push('COUNT', count.toString()); - - if (options?.MAXLEN !== undefined) { - args.push('MAXLEN', options.MAXLEN.toString()); - } - - return args; + parser.push('COUNT', count.toString()); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPUSH.spec.ts b/packages/client/lib/commands/LPUSH.spec.ts index 8d2ddb5ccc..09c7d9da77 100644 --- a/packages/client/lib/commands/LPUSH.spec.ts +++ b/packages/client/lib/commands/LPUSH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPUSH from './LPUSH'; +import { parseArgs } from './generic-transformers'; describe('LPUSH', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - LPUSH.transformArguments('key', 'field'), + parseArgs(LPUSH, 'key', 'field'), ['LPUSH', 'key', 'field'] ); }); it('array', () => { assert.deepEqual( - LPUSH.transformArguments('key', ['1', '2']), + parseArgs(LPUSH, 'key', ['1', '2']), ['LPUSH', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/LPUSH.ts b/packages/client/lib/commands/LPUSH.ts index 714db2ae9a..293029034e 100644 --- a/packages/client/lib/commands/LPUSH.ts +++ b/packages/client/lib/commands/LPUSH.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, elements: RedisVariadicArgument) { - return pushVariadicArguments(['LPUSH', key], elements); + parseCommand(parser: CommandParser, key: RedisArgument, elements: RedisVariadicArgument) { + parser.push('LPUSH'); + parser.pushKey(key); + parser.pushVariadic(elements); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LPUSHX.spec.ts b/packages/client/lib/commands/LPUSHX.spec.ts index f7dafe025c..179a0ddb29 100644 --- a/packages/client/lib/commands/LPUSHX.spec.ts +++ b/packages/client/lib/commands/LPUSHX.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LPUSHX from './LPUSHX'; +import { parseArgs } from './generic-transformers'; describe('LPUSHX', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - LPUSHX.transformArguments('key', 'element'), + parseArgs(LPUSHX, 'key', 'element'), ['LPUSHX', 'key', 'element'] ); }); it('array', () => { assert.deepEqual( - LPUSHX.transformArguments('key', ['1', '2']), + parseArgs(LPUSHX, 'key', ['1', '2']), ['LPUSHX', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/LPUSHX.ts b/packages/client/lib/commands/LPUSHX.ts index d6dceda6d0..98dd51a7ac 100644 --- a/packages/client/lib/commands/LPUSHX.ts +++ b/packages/client/lib/commands/LPUSHX.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, elements: RedisVariadicArgument) { - return pushVariadicArguments(['LPUSHX', key], elements); + parseCommand(parser: CommandParser, key: RedisArgument, elements: RedisVariadicArgument) { + parser.push('LPUSHX'); + parser.pushKey(key); + parser.pushVariadic(elements); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LRANGE.spec.ts b/packages/client/lib/commands/LRANGE.spec.ts index 3e768cc073..c0bb046d89 100644 --- a/packages/client/lib/commands/LRANGE.spec.ts +++ b/packages/client/lib/commands/LRANGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LRANGE from './LRANGE'; +import { parseArgs } from './generic-transformers'; describe('LRANGE', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - LRANGE.transformArguments('key', 0, -1), + parseArgs(LRANGE, 'key', 0, -1), ['LRANGE', 'key', '0', '-1'] ); }); diff --git a/packages/client/lib/commands/LRANGE.ts b/packages/client/lib/commands/LRANGE.ts index 4b4b3488ba..ab033dd88a 100644 --- a/packages/client/lib/commands/LRANGE.ts +++ b/packages/client/lib/commands/LRANGE.ts @@ -1,19 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - start: number, - stop: number -) { - return [ - 'LRANGE', - key, - start.toString(), - stop.toString() - ]; + parseCommand(parser: CommandParser, key: RedisArgument, start: number, stop: number) { + parser.push('LRANGE'); + parser.pushKey(key); + parser.push(start.toString(), stop.toString()) }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LREM.spec.ts b/packages/client/lib/commands/LREM.spec.ts index 1a35dab7c5..2a36d8ee2f 100644 --- a/packages/client/lib/commands/LREM.spec.ts +++ b/packages/client/lib/commands/LREM.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LREM from './LREM'; +import { parseArgs } from './generic-transformers'; describe('LREM', () => { it('transformArguments', () => { assert.deepEqual( - LREM.transformArguments('key', 0, 'element'), + parseArgs(LREM, 'key', 0, 'element'), ['LREM', 'key', '0', 'element'] ); }); diff --git a/packages/client/lib/commands/LREM.ts b/packages/client/lib/commands/LREM.ts index dbd2002be8..bb97e3882e 100644 --- a/packages/client/lib/commands/LREM.ts +++ b/packages/client/lib/commands/LREM.ts @@ -1,19 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - count: number, - element: RedisArgument - ) { - return [ - 'LREM', - key, - count.toString(), - element - ]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number, element: RedisArgument) { + parser.push('LREM'); + parser.pushKey(key); + parser.push(count.toString()); + parser.push(element); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/LSET.spec.ts b/packages/client/lib/commands/LSET.spec.ts index ae4b1bf9f2..c752294240 100644 --- a/packages/client/lib/commands/LSET.spec.ts +++ b/packages/client/lib/commands/LSET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LSET from './LSET'; +import { parseArgs } from './generic-transformers'; describe('LSET', () => { it('transformArguments', () => { assert.deepEqual( - LSET.transformArguments('key', 0, 'element'), + parseArgs(LSET, 'key', 0, 'element'), ['LSET', 'key', '0', 'element'] ); }); diff --git a/packages/client/lib/commands/LSET.ts b/packages/client/lib/commands/LSET.ts index edb86baae0..0fe646fbb7 100644 --- a/packages/client/lib/commands/LSET.ts +++ b/packages/client/lib/commands/LSET.ts @@ -1,19 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - index: number, - element: RedisArgument - ) { - return [ - 'LSET', - key, - index.toString(), - element - ]; + parseCommand(parser: CommandParser, key: RedisArgument, index: number, element: RedisArgument) { + parser.push('LSET'); + parser.pushKey(key); + parser.push(index.toString(), element); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/LTRIM.spec.ts b/packages/client/lib/commands/LTRIM.spec.ts index 3edc366973..5b6d77c91d 100644 --- a/packages/client/lib/commands/LTRIM.spec.ts +++ b/packages/client/lib/commands/LTRIM.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LTRIM from './LTRIM'; +import { parseArgs } from './generic-transformers'; describe('LTRIM', () => { it('transformArguments', () => { assert.deepEqual( - LTRIM.transformArguments('key', 0, -1), + parseArgs(LTRIM, 'key', 0, -1), ['LTRIM', 'key', '0', '-1'] ); }); diff --git a/packages/client/lib/commands/LTRIM.ts b/packages/client/lib/commands/LTRIM.ts index b80aa6264e..acc7e767d0 100644 --- a/packages/client/lib/commands/LTRIM.ts +++ b/packages/client/lib/commands/LTRIM.ts @@ -1,18 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - start: number, - stop: number - ) { - return [ - 'LTRIM', - key, - start.toString(), - stop.toString() - ]; + parseCommand(parser: CommandParser, key: RedisArgument, start: number, stop: number) { + parser.push('LTRIM'); + parser.pushKey(key); + parser.push(start.toString(), stop.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MEMORY_DOCTOR.spec.ts b/packages/client/lib/commands/MEMORY_DOCTOR.spec.ts index e1d718d7aa..9d822f8e07 100644 --- a/packages/client/lib/commands/MEMORY_DOCTOR.spec.ts +++ b/packages/client/lib/commands/MEMORY_DOCTOR.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MEMORY_DOCTOR from './MEMORY_DOCTOR'; +import { parseArgs } from './generic-transformers'; describe('MEMORY DOCTOR', () => { it('transformArguments', () => { assert.deepEqual( - MEMORY_DOCTOR.transformArguments(), + parseArgs(MEMORY_DOCTOR), ['MEMORY', 'DOCTOR'] ); }); diff --git a/packages/client/lib/commands/MEMORY_DOCTOR.ts b/packages/client/lib/commands/MEMORY_DOCTOR.ts index 6f8eb29ef2..3a2d808db1 100644 --- a/packages/client/lib/commands/MEMORY_DOCTOR.ts +++ b/packages/client/lib/commands/MEMORY_DOCTOR.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['MEMORY', 'DOCTOR']; + parseCommand(parser: CommandParser) { + parser.push('MEMORY', 'DOCTOR'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts b/packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts index 8484fcbf0b..a4a85f5b99 100644 --- a/packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts +++ b/packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MEMORY_MALLOC_STATS from './MEMORY_MALLOC-STATS'; +import { parseArgs } from './generic-transformers'; describe('MEMORY MALLOC-STATS', () => { it('transformArguments', () => { assert.deepEqual( - MEMORY_MALLOC_STATS.transformArguments(), + parseArgs(MEMORY_MALLOC_STATS), ['MEMORY', 'MALLOC-STATS'] ); }); diff --git a/packages/client/lib/commands/MEMORY_MALLOC-STATS.ts b/packages/client/lib/commands/MEMORY_MALLOC-STATS.ts index 31b01a49b5..af6b5db334 100644 --- a/packages/client/lib/commands/MEMORY_MALLOC-STATS.ts +++ b/packages/client/lib/commands/MEMORY_MALLOC-STATS.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['MEMORY', 'MALLOC-STATS']; + parseCommand(parser: CommandParser) { + parser.push('MEMORY', 'MALLOC-STATS'); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/MEMORY_PURGE.spec.ts b/packages/client/lib/commands/MEMORY_PURGE.spec.ts index 41b01f87c4..be5fb738b0 100644 --- a/packages/client/lib/commands/MEMORY_PURGE.spec.ts +++ b/packages/client/lib/commands/MEMORY_PURGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MEMORY_PURGE from './MEMORY_PURGE'; +import { parseArgs } from './generic-transformers'; describe('MEMORY PURGE', () => { it('transformArguments', () => { assert.deepEqual( - MEMORY_PURGE.transformArguments(), + parseArgs(MEMORY_PURGE), ['MEMORY', 'PURGE'] ); }); diff --git a/packages/client/lib/commands/MEMORY_PURGE.ts b/packages/client/lib/commands/MEMORY_PURGE.ts index b4c48d4010..bbd0289078 100644 --- a/packages/client/lib/commands/MEMORY_PURGE.ts +++ b/packages/client/lib/commands/MEMORY_PURGE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments() { - return ['MEMORY', 'PURGE']; + parseCommand(parser: CommandParser) { + parser.push('MEMORY', 'PURGE'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MEMORY_STATS.spec.ts b/packages/client/lib/commands/MEMORY_STATS.spec.ts index 6d5f5b8690..6aad05116a 100644 --- a/packages/client/lib/commands/MEMORY_STATS.spec.ts +++ b/packages/client/lib/commands/MEMORY_STATS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MEMORY_STATS from './MEMORY_STATS'; +import { parseArgs } from './generic-transformers'; describe('MEMORY STATS', () => { it('transformArguments', () => { assert.deepEqual( - MEMORY_STATS.transformArguments(), + parseArgs(MEMORY_STATS), ['MEMORY', 'STATS'] ); }); diff --git a/packages/client/lib/commands/MEMORY_STATS.ts b/packages/client/lib/commands/MEMORY_STATS.ts index f38a0e5f29..33410535aa 100644 --- a/packages/client/lib/commands/MEMORY_STATS.ts +++ b/packages/client/lib/commands/MEMORY_STATS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, ArrayReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; import { transformDoubleReply } from './generic-transformers'; @@ -35,10 +36,10 @@ export type MemoryStatsReply = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['MEMORY', 'STATS']; + parseCommand(parser: CommandParser) { + parser.push('MEMORY', 'STATS'); }, transformReply: { 2: (rawReply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/commands/MEMORY_USAGE.spec.ts b/packages/client/lib/commands/MEMORY_USAGE.spec.ts index 250a688425..edf673564e 100644 --- a/packages/client/lib/commands/MEMORY_USAGE.spec.ts +++ b/packages/client/lib/commands/MEMORY_USAGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MEMORY_USAGE from './MEMORY_USAGE'; +import { parseArgs } from './generic-transformers'; describe('MEMORY USAGE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - MEMORY_USAGE.transformArguments('key'), + parseArgs(MEMORY_USAGE, 'key'), ['MEMORY', 'USAGE', 'key'] ); }); it('with SAMPLES', () => { assert.deepEqual( - MEMORY_USAGE.transformArguments('key', { + parseArgs(MEMORY_USAGE, 'key', { SAMPLES: 1 }), ['MEMORY', 'USAGE', 'key', 'SAMPLES', '1'] diff --git a/packages/client/lib/commands/MEMORY_USAGE.ts b/packages/client/lib/commands/MEMORY_USAGE.ts index 78b079c2c1..6e85438dbe 100644 --- a/packages/client/lib/commands/MEMORY_USAGE.ts +++ b/packages/client/lib/commands/MEMORY_USAGE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, NullReply, Command, RedisArgument } from '../RESP/types'; export interface MemoryUsageOptions { @@ -5,16 +6,14 @@ export interface MemoryUsageOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: MemoryUsageOptions) { - const args = ['MEMORY', 'USAGE', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: MemoryUsageOptions) { + parser.push('MEMORY', 'USAGE'); + parser.pushKey(key); if (options?.SAMPLES) { - args.push('SAMPLES', options.SAMPLES.toString()); + parser.push('SAMPLES', options.SAMPLES.toString()); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/MGET.spec.ts b/packages/client/lib/commands/MGET.spec.ts index 296702a1a0..048fa6f0a5 100644 --- a/packages/client/lib/commands/MGET.spec.ts +++ b/packages/client/lib/commands/MGET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MGET from './MGET'; +import { parseArgs } from './generic-transformers'; describe('MGET', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - MGET.transformArguments(['1', '2']), + parseArgs(MGET, ['1', '2']), ['MGET', '1', '2'] ); }); diff --git a/packages/client/lib/commands/MGET.ts b/packages/client/lib/commands/MGET.ts index 0f0f9e52ff..ce1e9ba778 100644 --- a/packages/client/lib/commands/MGET.ts +++ b/packages/client/lib/commands/MGET.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(keys: Array) { - return ['MGET', ...keys]; + parseCommand(parser: CommandParser, keys: Array) { + parser.push('MGET'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => Array } as const satisfies Command; diff --git a/packages/client/lib/commands/MIGRATE.spec.ts b/packages/client/lib/commands/MIGRATE.spec.ts index 880d59a09c..dd2fbdc82f 100644 --- a/packages/client/lib/commands/MIGRATE.spec.ts +++ b/packages/client/lib/commands/MIGRATE.spec.ts @@ -1,25 +1,26 @@ import { strict as assert } from 'node:assert'; import MIGRATE from './MIGRATE'; +import { parseArgs } from './generic-transformers'; describe('MIGRATE', () => { describe('transformArguments', () => { it('single key', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10), + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10), ['MIGRATE', '127.0.0.1', '6379', 'key', '0', '10'] ); }); it('multiple keys', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, ['1', '2'], 0, 10), + parseArgs(MIGRATE, '127.0.0.1', 6379, ['1', '2'], 0, 10), ['MIGRATE', '127.0.0.1', '6379', '', '0', '10', 'KEYS', '1', '2'] ); }); it('with COPY', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10, { + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10, { COPY: true }), ['MIGRATE', '127.0.0.1', '6379', 'key', '0', '10', 'COPY'] @@ -28,7 +29,7 @@ describe('MIGRATE', () => { it('with REPLACE', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10, { + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10, { REPLACE: true }), ['MIGRATE', '127.0.0.1', '6379', 'key', '0', '10', 'REPLACE'] @@ -38,7 +39,7 @@ describe('MIGRATE', () => { describe('with AUTH', () => { it('password only', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10, { + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10, { AUTH: { password: 'password' } @@ -49,7 +50,7 @@ describe('MIGRATE', () => { it('username & password', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10, { + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10, { AUTH: { username: 'username', password: 'password' @@ -62,7 +63,7 @@ describe('MIGRATE', () => { it('with COPY, REPLACE, AUTH', () => { assert.deepEqual( - MIGRATE.transformArguments('127.0.0.1', 6379, 'key', 0, 10, { + parseArgs(MIGRATE, '127.0.0.1', 6379, 'key', 0, 10, { COPY: true, REPLACE: true, AUTH: { diff --git a/packages/client/lib/commands/MIGRATE.ts b/packages/client/lib/commands/MIGRATE.ts index 4821f93fcf..15345060aa 100644 --- a/packages/client/lib/commands/MIGRATE.ts +++ b/packages/client/lib/commands/MIGRATE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; import { AuthOptions } from './AUTH'; @@ -9,7 +10,8 @@ export interface MigrateOptions { export default { IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, host: RedisArgument, port: number, key: RedisArgument | Array, @@ -17,37 +19,37 @@ export default { timeout: number, options?: MigrateOptions ) { - const args = ['MIGRATE', host, port.toString()], - isKeyArray = Array.isArray(key); + parser.push('MIGRATE', host, port.toString()); + const isKeyArray = Array.isArray(key); if (isKeyArray) { - args.push(''); + parser.push(''); } else { - args.push(key); + parser.push(key); } - args.push( + parser.push( destinationDb.toString(), timeout.toString() ); if (options?.COPY) { - args.push('COPY'); + parser.push('COPY'); } if (options?.REPLACE) { - args.push('REPLACE'); + parser.push('REPLACE'); } if (options?.AUTH) { if (options.AUTH.username) { - args.push( + parser.push( 'AUTH2', options.AUTH.username, options.AUTH.password ); } else { - args.push( + parser.push( 'AUTH', options.AUTH.password ); @@ -55,13 +57,9 @@ export default { } if (isKeyArray) { - args.push( - 'KEYS', - ...key - ); + parser.push('KEYS'); + parser.pushVariadic(key); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MODULE_LIST.spec.ts b/packages/client/lib/commands/MODULE_LIST.spec.ts index 9c1d387438..0aab973cf2 100644 --- a/packages/client/lib/commands/MODULE_LIST.spec.ts +++ b/packages/client/lib/commands/MODULE_LIST.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import MODULE_LIST from './MODULE_LIST'; +import { parseArgs } from './generic-transformers'; describe('MODULE LIST', () => { it('transformArguments', () => { assert.deepEqual( - MODULE_LIST.transformArguments(), + parseArgs(MODULE_LIST), ['MODULE', 'LIST'] ); }); diff --git a/packages/client/lib/commands/MODULE_LIST.ts b/packages/client/lib/commands/MODULE_LIST.ts index 5ddd4e91ff..85203138f5 100644 --- a/packages/client/lib/commands/MODULE_LIST.ts +++ b/packages/client/lib/commands/MODULE_LIST.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; export type ModuleListReply = ArrayReply>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['MODULE', 'LIST']; + parseCommand(parser: CommandParser) { + parser.push('MODULE', 'LIST'); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/MODULE_LOAD.spec.ts b/packages/client/lib/commands/MODULE_LOAD.spec.ts index 3b7b9dd00a..418dd9b5da 100644 --- a/packages/client/lib/commands/MODULE_LOAD.spec.ts +++ b/packages/client/lib/commands/MODULE_LOAD.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import MODULE_LOAD from './MODULE_LOAD'; +import { parseArgs } from './generic-transformers'; describe('MODULE LOAD', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - MODULE_LOAD.transformArguments('path'), + parseArgs(MODULE_LOAD, 'path'), ['MODULE', 'LOAD', 'path'] ); }); it('with module args', () => { assert.deepEqual( - MODULE_LOAD.transformArguments('path', ['1', '2']), + parseArgs(MODULE_LOAD, 'path', ['1', '2']), ['MODULE', 'LOAD', 'path', '1', '2'] ); }); diff --git a/packages/client/lib/commands/MODULE_LOAD.ts b/packages/client/lib/commands/MODULE_LOAD.ts index 82c5b81a90..ceb90c1c35 100644 --- a/packages/client/lib/commands/MODULE_LOAD.ts +++ b/packages/client/lib/commands/MODULE_LOAD.ts @@ -1,16 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(path: RedisArgument, moduleArguments?: Array) { - const args = ['MODULE', 'LOAD', path]; + parseCommand(parser: CommandParser, path: RedisArgument, moduleArguments?: Array) { + parser.push('MODULE', 'LOAD', path); if (moduleArguments) { - return args.concat(moduleArguments); + parser.push(...moduleArguments); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MODULE_UNLOAD.spec.ts b/packages/client/lib/commands/MODULE_UNLOAD.spec.ts index e33fb3a5f4..581f41e03c 100644 --- a/packages/client/lib/commands/MODULE_UNLOAD.spec.ts +++ b/packages/client/lib/commands/MODULE_UNLOAD.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import MODULE_UNLOAD from './MODULE_UNLOAD'; +import { parseArgs } from './generic-transformers'; describe('MODULE UNLOAD', () => { it('transformArguments', () => { assert.deepEqual( - MODULE_UNLOAD.transformArguments('name'), + parseArgs(MODULE_UNLOAD, 'name'), ['MODULE', 'UNLOAD', 'name'] ); }); diff --git a/packages/client/lib/commands/MODULE_UNLOAD.ts b/packages/client/lib/commands/MODULE_UNLOAD.ts index 3a2bc05c0e..1acc359d0d 100644 --- a/packages/client/lib/commands/MODULE_UNLOAD.ts +++ b/packages/client/lib/commands/MODULE_UNLOAD.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(name: RedisArgument) { - return ['MODULE', 'UNLOAD', name]; + parseCommand(parser: CommandParser, name: RedisArgument) { + parser.push('MODULE', 'UNLOAD', name); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MOVE.spec.ts b/packages/client/lib/commands/MOVE.spec.ts index e767568e72..91a01378b2 100644 --- a/packages/client/lib/commands/MOVE.spec.ts +++ b/packages/client/lib/commands/MOVE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MOVE from './MOVE'; +import { parseArgs } from './generic-transformers'; describe('MOVE', () => { it('transformArguments', () => { assert.deepEqual( - MOVE.transformArguments('key', 1), + parseArgs(MOVE, 'key', 1), ['MOVE', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/MOVE.ts b/packages/client/lib/commands/MOVE.ts index 60aac4b145..8a6c5427fb 100644 --- a/packages/client/lib/commands/MOVE.ts +++ b/packages/client/lib/commands/MOVE.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, db: number) { - return ['MOVE', key, db.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, db: number) { + parser.push('MOVE'); + parser.pushKey(key); + parser.push(db.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/MSET.spec.ts b/packages/client/lib/commands/MSET.spec.ts index 5435e28310..cfb14eceb0 100644 --- a/packages/client/lib/commands/MSET.spec.ts +++ b/packages/client/lib/commands/MSET.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MSET from './MSET'; +import { parseArgs } from './generic-transformers'; describe('MSET', () => { describe('transformArguments', () => { it("['key1', 'value1', 'key2', 'value2']", () => { assert.deepEqual( - MSET.transformArguments(['key1', 'value1', 'key2', 'value2']), + parseArgs(MSET, ['key1', 'value1', 'key2', 'value2']), ['MSET', 'key1', 'value1', 'key2', 'value2'] ); }); it("[['key1', 'value1'], ['key2', 'value2']]", () => { assert.deepEqual( - MSET.transformArguments([['key1', 'value1'], ['key2', 'value2']]), + parseArgs(MSET, [['key1', 'value1'], ['key2', 'value2']]), ['MSET', 'key1', 'value1', 'key2', 'value2'] ); }); it("{key1: 'value1'. key2: 'value2'}", () => { assert.deepEqual( - MSET.transformArguments({ key1: 'value1', key2: 'value2' }), + parseArgs(MSET, { key1: 'value1', key2: 'value2' }), ['MSET', 'key1', 'value1', 'key2', 'value2'] ); }); diff --git a/packages/client/lib/commands/MSET.ts b/packages/client/lib/commands/MSET.ts index 136fde3e7f..f761854f09 100644 --- a/packages/client/lib/commands/MSET.ts +++ b/packages/client/lib/commands/MSET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export type MSetArguments = @@ -5,23 +6,36 @@ export type MSetArguments = Array | Record; -export function mSetArguments(command: string, toSet: MSetArguments) { - const args: Array = [command]; - +export function parseMSetArguments(parser: CommandParser, toSet: MSetArguments) { if (Array.isArray(toSet)) { - args.push(...toSet.flat()); + if (toSet.length == 0) { + throw new Error("empty toSet Argument") + } + if (Array.isArray(toSet[0])) { + for (const tuple of (toSet as Array<[RedisArgument, RedisArgument]>)) { + parser.pushKey(tuple[0]); + parser.push(tuple[1]); + } + } else { + const arr = toSet as Array; + for (let i=0; i < arr.length; i += 2) { + parser.pushKey(arr[i]); + parser.push(arr[i+1]); + } + } } else { for (const tuple of Object.entries(toSet)) { - args.push(...tuple); + parser.pushKey(tuple[0]); + parser.push(tuple[1]); } } - - return args; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: mSetArguments.bind(undefined, 'MSET'), + parseCommand(parser: CommandParser, toSet: MSetArguments) { + parser.push('MSET'); + return parseMSetArguments(parser, toSet); + }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/MSETNX.spec.ts b/packages/client/lib/commands/MSETNX.spec.ts index 1583d04a94..0a9f636abc 100644 --- a/packages/client/lib/commands/MSETNX.spec.ts +++ b/packages/client/lib/commands/MSETNX.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MSETNX from './MSETNX'; +import { parseArgs } from './generic-transformers'; describe('MSETNX', () => { describe('transformArguments', () => { it("['key1', 'value1', 'key2', 'value2']", () => { assert.deepEqual( - MSETNX.transformArguments(['key1', 'value1', 'key2', 'value2']), + parseArgs(MSETNX, ['key1', 'value1', 'key2', 'value2']), ['MSETNX', 'key1', 'value1', 'key2', 'value2'] ); }); it("[['key1', 'value1'], ['key2', 'value2']]", () => { assert.deepEqual( - MSETNX.transformArguments([['key1', 'value1'], ['key2', 'value2']]), + parseArgs(MSETNX, [['key1', 'value1'], ['key2', 'value2']]), ['MSETNX', 'key1', 'value1', 'key2', 'value2'] ); }); it("{key1: 'value1'. key2: 'value2'}", () => { assert.deepEqual( - MSETNX.transformArguments({ key1: 'value1', key2: 'value2' }), + parseArgs(MSETNX, { key1: 'value1', key2: 'value2' }), ['MSETNX', 'key1', 'value1', 'key2', 'value2'] ); }); diff --git a/packages/client/lib/commands/MSETNX.ts b/packages/client/lib/commands/MSETNX.ts index 4867b3ea09..3ecce9525d 100644 --- a/packages/client/lib/commands/MSETNX.ts +++ b/packages/client/lib/commands/MSETNX.ts @@ -1,9 +1,12 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; -import { mSetArguments } from './MSET'; +import { MSetArguments, parseMSetArguments } from './MSET'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: mSetArguments.bind(undefined, 'MSETNX'), + parseCommand(parser: CommandParser, toSet: MSetArguments) { + parser.push('MSETNX'); + return parseMSetArguments(parser, toSet); + }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/OBJECT_ENCODING.spec.ts b/packages/client/lib/commands/OBJECT_ENCODING.spec.ts index 48146f1292..34f82be9b8 100644 --- a/packages/client/lib/commands/OBJECT_ENCODING.spec.ts +++ b/packages/client/lib/commands/OBJECT_ENCODING.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJECT_ENCODING from './OBJECT_ENCODING'; +import { parseArgs } from './generic-transformers'; describe('OBJECT ENCODING', () => { it('transformArguments', () => { assert.deepEqual( - OBJECT_ENCODING.transformArguments('key'), + parseArgs(OBJECT_ENCODING, 'key'), ['OBJECT', 'ENCODING', 'key'] ); }); diff --git a/packages/client/lib/commands/OBJECT_ENCODING.ts b/packages/client/lib/commands/OBJECT_ENCODING.ts index e74c3f99eb..3a795f6fb6 100644 --- a/packages/client/lib/commands/OBJECT_ENCODING.ts +++ b/packages/client/lib/commands/OBJECT_ENCODING.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['OBJECT', 'ENCODING', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('OBJECT', 'ENCODING'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/OBJECT_FREQ.spec.ts b/packages/client/lib/commands/OBJECT_FREQ.spec.ts index cbad72c308..081501b12e 100644 --- a/packages/client/lib/commands/OBJECT_FREQ.spec.ts +++ b/packages/client/lib/commands/OBJECT_FREQ.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJECT_FREQ from './OBJECT_FREQ'; +import { parseArgs } from './generic-transformers'; describe('OBJECT FREQ', () => { it('transformArguments', () => { assert.deepEqual( - OBJECT_FREQ.transformArguments('key'), + parseArgs(OBJECT_FREQ, 'key'), ['OBJECT', 'FREQ', 'key'] ); }); diff --git a/packages/client/lib/commands/OBJECT_FREQ.ts b/packages/client/lib/commands/OBJECT_FREQ.ts index b6757c6c57..dad1124b10 100644 --- a/packages/client/lib/commands/OBJECT_FREQ.ts +++ b/packages/client/lib/commands/OBJECT_FREQ.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['OBJECT', 'FREQ', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('OBJECT', 'FREQ'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/OBJECT_IDLETIME.spec.ts b/packages/client/lib/commands/OBJECT_IDLETIME.spec.ts index 51866427c8..30d47b8133 100644 --- a/packages/client/lib/commands/OBJECT_IDLETIME.spec.ts +++ b/packages/client/lib/commands/OBJECT_IDLETIME.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJECT_IDLETIME from './OBJECT_IDLETIME'; +import { parseArgs } from './generic-transformers'; describe('OBJECT IDLETIME', () => { it('transformArguments', () => { assert.deepEqual( - OBJECT_IDLETIME.transformArguments('key'), + parseArgs(OBJECT_IDLETIME, 'key'), ['OBJECT', 'IDLETIME', 'key'] ); }); diff --git a/packages/client/lib/commands/OBJECT_IDLETIME.ts b/packages/client/lib/commands/OBJECT_IDLETIME.ts index f0fef24e2d..2bd32f4e65 100644 --- a/packages/client/lib/commands/OBJECT_IDLETIME.ts +++ b/packages/client/lib/commands/OBJECT_IDLETIME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['OBJECT', 'IDLETIME', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('OBJECT', 'IDLETIME'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts b/packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts index f4309786eb..8bac08a2e5 100644 --- a/packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts +++ b/packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJECT_REFCOUNT from './OBJECT_REFCOUNT'; +import { parseArgs } from './generic-transformers'; describe('OBJECT REFCOUNT', () => { it('transformArguments', () => { assert.deepEqual( - OBJECT_REFCOUNT.transformArguments('key'), + parseArgs(OBJECT_REFCOUNT, 'key'), ['OBJECT', 'REFCOUNT', 'key'] ); }); diff --git a/packages/client/lib/commands/OBJECT_REFCOUNT.ts b/packages/client/lib/commands/OBJECT_REFCOUNT.ts index c8381a76bf..4bee4dea60 100644 --- a/packages/client/lib/commands/OBJECT_REFCOUNT.ts +++ b/packages/client/lib/commands/OBJECT_REFCOUNT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['OBJECT', 'REFCOUNT', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('OBJECT', 'REFCOUNT'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PERSIST.spec.ts b/packages/client/lib/commands/PERSIST.spec.ts index d778a1c0a5..fff6d7b3a7 100644 --- a/packages/client/lib/commands/PERSIST.spec.ts +++ b/packages/client/lib/commands/PERSIST.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PERSIST from './PERSIST'; +import { parseArgs } from './generic-transformers'; describe('PERSIST', () => { it('transformArguments', () => { assert.deepEqual( - PERSIST.transformArguments('key'), + parseArgs(PERSIST, 'key'), ['PERSIST', 'key'] ); }); diff --git a/packages/client/lib/commands/PERSIST.ts b/packages/client/lib/commands/PERSIST.ts index 64637fabc1..a1d3152366 100644 --- a/packages/client/lib/commands/PERSIST.ts +++ b/packages/client/lib/commands/PERSIST.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument) { - return ['PERSIST', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('PERSIST'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PEXPIRE.spec.ts b/packages/client/lib/commands/PEXPIRE.spec.ts index 61bfe69e9a..368bc9b490 100644 --- a/packages/client/lib/commands/PEXPIRE.spec.ts +++ b/packages/client/lib/commands/PEXPIRE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PEXPIRE from './PEXPIRE'; +import { parseArgs } from './generic-transformers'; describe('PEXPIRE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - PEXPIRE.transformArguments('key', 1), + parseArgs(PEXPIRE, 'key', 1), ['PEXPIRE', 'key', '1'] ); }); it('with set option', () => { assert.deepEqual( - PEXPIRE.transformArguments('key', 1, 'GT'), + parseArgs(PEXPIRE, 'key', 1, 'GT'), ['PEXPIRE', 'key', '1', 'GT'] ); }); diff --git a/packages/client/lib/commands/PEXPIRE.ts b/packages/client/lib/commands/PEXPIRE.ts index 4d64281e92..4053f46c8e 100644 --- a/packages/client/lib/commands/PEXPIRE.ts +++ b/packages/client/lib/commands/PEXPIRE.ts @@ -1,20 +1,21 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, ms: number, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['PEXPIRE', key, ms.toString()]; + parser.push('PEXPIRE'); + parser.pushKey(key); + parser.push(ms.toString()); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PEXPIREAT.spec.ts b/packages/client/lib/commands/PEXPIREAT.spec.ts index 117c5b512e..f105392040 100644 --- a/packages/client/lib/commands/PEXPIREAT.spec.ts +++ b/packages/client/lib/commands/PEXPIREAT.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PEXPIREAT from './PEXPIREAT'; +import { parseArgs } from './generic-transformers'; describe('PEXPIREAT', () => { describe('transformArguments', () => { it('number', () => { assert.deepEqual( - PEXPIREAT.transformArguments('key', 1), + parseArgs(PEXPIREAT, 'key', 1), ['PEXPIREAT', 'key', '1'] ); }); @@ -14,14 +15,14 @@ describe('PEXPIREAT', () => { it('date', () => { const d = new Date(); assert.deepEqual( - PEXPIREAT.transformArguments('key', d), + parseArgs(PEXPIREAT, 'key', d), ['PEXPIREAT', 'key', d.getTime().toString()] ); }); it('with set option', () => { assert.deepEqual( - PEXPIREAT.transformArguments('key', 1, 'XX'), + parseArgs(PEXPIREAT, 'key', 1, 'XX'), ['PEXPIREAT', 'key', '1', 'XX'] ); }); diff --git a/packages/client/lib/commands/PEXPIREAT.ts b/packages/client/lib/commands/PEXPIREAT.ts index cbae589fba..e454447c97 100644 --- a/packages/client/lib/commands/PEXPIREAT.ts +++ b/packages/client/lib/commands/PEXPIREAT.ts @@ -1,21 +1,22 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { transformPXAT } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, msTimestamp: number | Date, mode?: 'NX' | 'XX' | 'GT' | 'LT' ) { - const args = ['PEXPIREAT', key, transformPXAT(msTimestamp)]; + parser.push('PEXPIREAT'); + parser.pushKey(key); + parser.push(transformPXAT(msTimestamp)); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PEXPIRETIME.spec.ts b/packages/client/lib/commands/PEXPIRETIME.spec.ts index 25a8293ec5..dbfc69e80d 100644 --- a/packages/client/lib/commands/PEXPIRETIME.spec.ts +++ b/packages/client/lib/commands/PEXPIRETIME.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PEXPIRETIME from './PEXPIRETIME'; +import { parseArgs } from './generic-transformers'; describe('PEXPIRETIME', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - PEXPIRETIME.transformArguments('key'), + parseArgs(PEXPIRETIME, 'key'), ['PEXPIRETIME', 'key'] ); }); diff --git a/packages/client/lib/commands/PEXPIRETIME.ts b/packages/client/lib/commands/PEXPIRETIME.ts index e228351fa0..b5d04eae23 100644 --- a/packages/client/lib/commands/PEXPIRETIME.ts +++ b/packages/client/lib/commands/PEXPIRETIME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['PEXPIRETIME', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('PEXPIRETIME'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PFADD.spec.ts b/packages/client/lib/commands/PFADD.spec.ts index 04ba44164d..55c4311e63 100644 --- a/packages/client/lib/commands/PFADD.spec.ts +++ b/packages/client/lib/commands/PFADD.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PFADD from './PFADD'; +import { parseArgs } from './generic-transformers'; describe('PFADD', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - PFADD.transformArguments('key', 'element'), + parseArgs(PFADD, 'key', 'element'), ['PFADD', 'key', 'element'] ); }); it('array', () => { assert.deepEqual( - PFADD.transformArguments('key', ['1', '2']), + parseArgs(PFADD, 'key', ['1', '2']), ['PFADD', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/PFADD.ts b/packages/client/lib/commands/PFADD.ts index d7f198fbe5..94c2d1d5ae 100644 --- a/packages/client/lib/commands/PFADD.ts +++ b/packages/client/lib/commands/PFADD.ts @@ -1,14 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, element?: RedisVariadicArgument) { - const args = ['PFADD', key]; - if (!element) return args; - - return pushVariadicArguments(args, element); + parseCommand(parser: CommandParser, key: RedisArgument, element?: RedisVariadicArgument) { + parser.push('PFADD') + parser.pushKey(key); + if (element) { + parser.pushVariadic(element); + } }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PFCOUNT.spec.ts b/packages/client/lib/commands/PFCOUNT.spec.ts index ebb54ea1d7..aec2ebecf0 100644 --- a/packages/client/lib/commands/PFCOUNT.spec.ts +++ b/packages/client/lib/commands/PFCOUNT.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PFCOUNT from './PFCOUNT'; +import { parseArgs } from './generic-transformers'; describe('PFCOUNT', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - PFCOUNT.transformArguments('key'), + parseArgs(PFCOUNT, 'key'), ['PFCOUNT', 'key'] ); }); it('array', () => { assert.deepEqual( - PFCOUNT.transformArguments(['1', '2']), + parseArgs(PFCOUNT, ['1', '2']), ['PFCOUNT', '1', '2'] ); }); diff --git a/packages/client/lib/commands/PFCOUNT.ts b/packages/client/lib/commands/PFCOUNT.ts index 5b46eb00d9..46d2e2ed71 100644 --- a/packages/client/lib/commands/PFCOUNT.ts +++ b/packages/client/lib/commands/PFCOUNT.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisVariadicArgument) { - return pushVariadicArguments(['PFCOUNT'], key); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('PFCOUNT'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PFMERGE.spec.ts b/packages/client/lib/commands/PFMERGE.spec.ts index bb2444b3ef..a286e93291 100644 --- a/packages/client/lib/commands/PFMERGE.spec.ts +++ b/packages/client/lib/commands/PFMERGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PFMERGE from './PFMERGE'; +import { parseArgs } from './generic-transformers'; describe('PFMERGE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - PFMERGE.transformArguments('destination', 'source'), + parseArgs(PFMERGE, 'destination', 'source'), ['PFMERGE', 'destination', 'source'] ); }); it('array', () => { assert.deepEqual( - PFMERGE.transformArguments('destination', ['1', '2']), + parseArgs(PFMERGE, 'destination', ['1', '2']), ['PFMERGE', 'destination', '1', '2'] ); }); diff --git a/packages/client/lib/commands/PFMERGE.ts b/packages/client/lib/commands/PFMERGE.ts index eeeeb5173d..e8eccf1aff 100644 --- a/packages/client/lib/commands/PFMERGE.ts +++ b/packages/client/lib/commands/PFMERGE.ts @@ -1,16 +1,18 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, - source?: RedisVariadicArgument + sources?: RedisVariadicArgument ) { - const args = ['PFMERGE', destination]; - if (!source) return args; - - return pushVariadicArguments(args, source); + parser.push('PFMERGE'); + parser.pushKey(destination); + if (sources) { + parser.pushKeys(sources); + } }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PING.spec.ts b/packages/client/lib/commands/PING.spec.ts index 0cd75a6a8d..56f513685f 100644 --- a/packages/client/lib/commands/PING.spec.ts +++ b/packages/client/lib/commands/PING.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PING from './PING'; +import { parseArgs } from './generic-transformers'; describe('PING', () => { describe('transformArguments', () => { it('default', () => { assert.deepEqual( - PING.transformArguments(), + parseArgs(PING), ['PING'] ); }); it('with message', () => { assert.deepEqual( - PING.transformArguments('message'), + parseArgs(PING, 'message'), ['PING', 'message'] ); }); diff --git a/packages/client/lib/commands/PING.ts b/packages/client/lib/commands/PING.ts index 7f6fd31047..26807eeeba 100644 --- a/packages/client/lib/commands/PING.ts +++ b/packages/client/lib/commands/PING.ts @@ -1,15 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(message?: RedisArgument) { - const args: Array = ['PING']; + parseCommand(parser: CommandParser, message?: RedisArgument) { + parser.push('PING'); if (message) { - args.push(message); + parser.push(message); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply | BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PSETEX.spec.ts b/packages/client/lib/commands/PSETEX.spec.ts index fd7bcd2dff..8580e2f8e9 100644 --- a/packages/client/lib/commands/PSETEX.spec.ts +++ b/packages/client/lib/commands/PSETEX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PSETEX from './PSETEX'; +import { parseArgs } from './generic-transformers'; describe('PSETEX', () => { it('transformArguments', () => { assert.deepEqual( - PSETEX.transformArguments('key', 1, 'value'), + parseArgs(PSETEX, 'key', 1, 'value'), ['PSETEX', 'key', '1', 'value'] ); }); diff --git a/packages/client/lib/commands/PSETEX.ts b/packages/client/lib/commands/PSETEX.ts index 4e345a1a1c..03a58546d6 100644 --- a/packages/client/lib/commands/PSETEX.ts +++ b/packages/client/lib/commands/PSETEX.ts @@ -1,18 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - ms: number, - value: RedisArgument - ) { - return [ - 'PSETEX', - key, - ms.toString(), - value - ]; + parseCommand(parser: CommandParser, key: RedisArgument, ms: number, value: RedisArgument) { + parser.push('PSETEX'); + parser.pushKey(key); + parser.push(ms.toString(), value); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/PTTL.spec.ts b/packages/client/lib/commands/PTTL.spec.ts index 65a9f5dd0f..deb04bad97 100644 --- a/packages/client/lib/commands/PTTL.spec.ts +++ b/packages/client/lib/commands/PTTL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PTTL from './PTTL'; +import { parseArgs } from './generic-transformers'; describe('PTTL', () => { it('transformArguments', () => { assert.deepEqual( - PTTL.transformArguments('key'), + parseArgs(PTTL, 'key'), ['PTTL', 'key'] ); }); diff --git a/packages/client/lib/commands/PTTL.ts b/packages/client/lib/commands/PTTL.ts index 3585433787..5717c51179 100644 --- a/packages/client/lib/commands/PTTL.ts +++ b/packages/client/lib/commands/PTTL.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['PTTL', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('PTTL'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PUBLISH.spec.ts b/packages/client/lib/commands/PUBLISH.spec.ts index ec1f108e5e..930adc8c4d 100644 --- a/packages/client/lib/commands/PUBLISH.spec.ts +++ b/packages/client/lib/commands/PUBLISH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBLISH from './PUBLISH'; +import { parseArgs } from './generic-transformers'; describe('PUBLISH', () => { it('transformArguments', () => { assert.deepEqual( - PUBLISH.transformArguments('channel', 'message'), + parseArgs(PUBLISH, 'channel', 'message'), ['PUBLISH', 'channel', 'message'] ); }); diff --git a/packages/client/lib/commands/PUBLISH.ts b/packages/client/lib/commands/PUBLISH.ts index e790ff16c4..557efd1883 100644 --- a/packages/client/lib/commands/PUBLISH.ts +++ b/packages/client/lib/commands/PUBLISH.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, IS_FORWARD_COMMAND: true, - transformArguments(channel: RedisArgument, message: RedisArgument) { - return ['PUBLISH', channel, message]; + parseCommand(parser: CommandParser, channel: RedisArgument, message: RedisArgument) { + parser.push('PUBLISH', channel, message); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts b/packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts index 2fe02523ed..369e339a49 100644 --- a/packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts +++ b/packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBSUB_CHANNELS from './PUBSUB_CHANNELS'; +import { parseArgs } from './generic-transformers'; describe('PUBSUB CHANNELS', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - PUBSUB_CHANNELS.transformArguments(), + parseArgs(PUBSUB_CHANNELS), ['PUBSUB', 'CHANNELS'] ); }); it('with pattern', () => { assert.deepEqual( - PUBSUB_CHANNELS.transformArguments('patter*'), + parseArgs(PUBSUB_CHANNELS, 'patter*'), ['PUBSUB', 'CHANNELS', 'patter*'] ); }); diff --git a/packages/client/lib/commands/PUBSUB_CHANNELS.ts b/packages/client/lib/commands/PUBSUB_CHANNELS.ts index 4bf7abd75d..0f53c79a78 100644 --- a/packages/client/lib/commands/PUBSUB_CHANNELS.ts +++ b/packages/client/lib/commands/PUBSUB_CHANNELS.ts @@ -1,16 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(pattern?: RedisArgument) { - const args: Array = ['PUBSUB', 'CHANNELS']; + parseCommand(parser: CommandParser, pattern?: RedisArgument) { + parser.push('PUBSUB', 'CHANNELS'); if (pattern) { - args.push(pattern); + parser.push(pattern); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts b/packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts index 43a2b4b5c0..d75256bb43 100644 --- a/packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts +++ b/packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBSUB_NUMPAT from './PUBSUB_NUMPAT'; +import { parseArgs } from './generic-transformers'; describe('PUBSUB NUMPAT', () => { it('transformArguments', () => { assert.deepEqual( - PUBSUB_NUMPAT.transformArguments(), + parseArgs(PUBSUB_NUMPAT), ['PUBSUB', 'NUMPAT'] ); }); diff --git a/packages/client/lib/commands/PUBSUB_NUMPAT.ts b/packages/client/lib/commands/PUBSUB_NUMPAT.ts index e8a0738dc7..173446e023 100644 --- a/packages/client/lib/commands/PUBSUB_NUMPAT.ts +++ b/packages/client/lib/commands/PUBSUB_NUMPAT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['PUBSUB', 'NUMPAT']; + parseCommand(parser: CommandParser) { + parser.push('PUBSUB', 'NUMPAT'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts b/packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts index 151dc21928..11339ae2bb 100644 --- a/packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts +++ b/packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBSUB_NUMSUB from './PUBSUB_NUMSUB'; +import { parseArgs } from './generic-transformers'; describe('PUBSUB NUMSUB', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - PUBSUB_NUMSUB.transformArguments(), + parseArgs(PUBSUB_NUMSUB), ['PUBSUB', 'NUMSUB'] ); }); it('string', () => { assert.deepEqual( - PUBSUB_NUMSUB.transformArguments('channel'), + parseArgs(PUBSUB_NUMSUB, 'channel'), ['PUBSUB', 'NUMSUB', 'channel'] ); }); it('array', () => { assert.deepEqual( - PUBSUB_NUMSUB.transformArguments(['1', '2']), + parseArgs(PUBSUB_NUMSUB, ['1', '2']), ['PUBSUB', 'NUMSUB', '1', '2'] ); }); diff --git a/packages/client/lib/commands/PUBSUB_NUMSUB.ts b/packages/client/lib/commands/PUBSUB_NUMSUB.ts index 1f7c41f5bd..cc74d5d8a7 100644 --- a/packages/client/lib/commands/PUBSUB_NUMSUB.ts +++ b/packages/client/lib/commands/PUBSUB_NUMSUB.ts @@ -1,15 +1,16 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, NumberReply, UnwrapReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(channels?: RedisVariadicArgument) { - const args = ['PUBSUB', 'NUMSUB']; + parseCommand(parser: CommandParser, channels?: RedisVariadicArgument) { + parser.push('PUBSUB', 'NUMSUB'); - if (channels) return pushVariadicArguments(args, channels); - - return args; + if (channels) { + parser.pushVariadic(channels); + } }, transformReply(rawReply: UnwrapReply>) { const reply = Object.create(null); diff --git a/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.spec.ts b/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.spec.ts index 77982b3467..36597a9cfd 100644 --- a/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.spec.ts +++ b/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBSUB_SHARDCHANNELS from './PUBSUB_SHARDCHANNELS'; +import { parseArgs } from './generic-transformers'; describe('PUBSUB SHARDCHANNELS', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('PUBSUB SHARDCHANNELS', () => { describe('transformArguments', () => { it('without pattern', () => { assert.deepEqual( - PUBSUB_SHARDCHANNELS.transformArguments(), + parseArgs(PUBSUB_SHARDCHANNELS), ['PUBSUB', 'SHARDCHANNELS'] ); }); it('with pattern', () => { assert.deepEqual( - PUBSUB_SHARDCHANNELS.transformArguments('patter*'), + parseArgs(PUBSUB_SHARDCHANNELS, 'patter*'), ['PUBSUB', 'SHARDCHANNELS', 'patter*'] ); }); diff --git a/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.ts b/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.ts index 74d78c0261..46ac2005fc 100644 --- a/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.ts +++ b/packages/client/lib/commands/PUBSUB_SHARDCHANNELS.ts @@ -1,16 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(pattern?: RedisArgument) { - const args: Array = ['PUBSUB', 'SHARDCHANNELS']; + parseCommand(parser: CommandParser, pattern?: RedisArgument) { + parser.push('PUBSUB', 'SHARDCHANNELS'); if (pattern) { - args.push(pattern); + parser.push(pattern); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.spec.ts b/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.spec.ts index e036a6eae5..e335941897 100644 --- a/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.spec.ts +++ b/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import PUBSUB_SHARDNUMSUB from './PUBSUB_SHARDNUMSUB'; +import { parseArgs } from './generic-transformers'; describe('PUBSUB SHARDNUMSUB', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,21 +9,21 @@ describe('PUBSUB SHARDNUMSUB', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - PUBSUB_SHARDNUMSUB.transformArguments(), + parseArgs(PUBSUB_SHARDNUMSUB), ['PUBSUB', 'SHARDNUMSUB'] ); }); it('string', () => { assert.deepEqual( - PUBSUB_SHARDNUMSUB.transformArguments('channel'), + parseArgs(PUBSUB_SHARDNUMSUB, 'channel'), ['PUBSUB', 'SHARDNUMSUB', 'channel'] ); }); it('array', () => { assert.deepEqual( - PUBSUB_SHARDNUMSUB.transformArguments(['1', '2']), + parseArgs(PUBSUB_SHARDNUMSUB, ['1', '2']), ['PUBSUB', 'SHARDNUMSUB', '1', '2'] ); }); diff --git a/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.ts b/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.ts index 0ef8247700..220eadeabe 100644 --- a/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.ts +++ b/packages/client/lib/commands/PUBSUB_SHARDNUMSUB.ts @@ -1,15 +1,15 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, NumberReply, UnwrapReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments(channels?: RedisVariadicArgument) { - const args = ['PUBSUB', 'SHARDNUMSUB']; + parseCommand(parser: CommandParser, channels?: RedisVariadicArgument) { + parser.push('PUBSUB', 'SHARDNUMSUB'); - if (channels) return pushVariadicArguments(args, channels); - - return args; + if (channels) { + parser.pushVariadic(channels); + } }, transformReply(reply: UnwrapReply>) { const transformedReply: Record = Object.create(null); diff --git a/packages/client/lib/commands/RANDOMKEY.spec.ts b/packages/client/lib/commands/RANDOMKEY.spec.ts index 31de60d7a9..f86617a3b7 100644 --- a/packages/client/lib/commands/RANDOMKEY.spec.ts +++ b/packages/client/lib/commands/RANDOMKEY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RANDOMKEY from './RANDOMKEY'; +import { parseArgs } from './generic-transformers'; describe('RANDOMKEY', () => { it('transformArguments', () => { assert.deepEqual( - RANDOMKEY.transformArguments(), + parseArgs(RANDOMKEY), ['RANDOMKEY'] ); }); diff --git a/packages/client/lib/commands/RANDOMKEY.ts b/packages/client/lib/commands/RANDOMKEY.ts index 42028ebbe3..97d040a0d1 100644 --- a/packages/client/lib/commands/RANDOMKEY.ts +++ b/packages/client/lib/commands/RANDOMKEY.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['RANDOMKEY']; + parseCommand(parser: CommandParser) { + parser.push('RANDOMKEY'); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/READONLY.spec.ts b/packages/client/lib/commands/READONLY.spec.ts index 14bb047349..ac30332233 100644 --- a/packages/client/lib/commands/READONLY.spec.ts +++ b/packages/client/lib/commands/READONLY.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import READONLY from './READONLY'; +import { parseArgs } from './generic-transformers'; describe('READONLY', () => { it('transformArguments', () => { assert.deepEqual( - READONLY.transformArguments(), + parseArgs(READONLY), ['READONLY'] ); }); diff --git a/packages/client/lib/commands/READONLY.ts b/packages/client/lib/commands/READONLY.ts index bb15834550..ce3300c532 100644 --- a/packages/client/lib/commands/READONLY.ts +++ b/packages/client/lib/commands/READONLY.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['READONLY']; + parseCommand(parser: CommandParser) { + parser.push('READONLY'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/READWRITE.spec.ts b/packages/client/lib/commands/READWRITE.spec.ts index 94a88a0dcc..cc3f99a5d1 100644 --- a/packages/client/lib/commands/READWRITE.spec.ts +++ b/packages/client/lib/commands/READWRITE.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import READWRITE from './READWRITE'; +import { parseArgs } from './generic-transformers'; describe('READWRITE', () => { it('transformArguments', () => { assert.deepEqual( - READWRITE.transformArguments(), + parseArgs(READWRITE), ['READWRITE'] ); }); diff --git a/packages/client/lib/commands/READWRITE.ts b/packages/client/lib/commands/READWRITE.ts index fe70e15d4c..7d9d8c7e00 100644 --- a/packages/client/lib/commands/READWRITE.ts +++ b/packages/client/lib/commands/READWRITE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['READWRITE']; + parseCommand(parser: CommandParser) { + parser.push('READWRITE'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RENAME.spec.ts b/packages/client/lib/commands/RENAME.spec.ts index cf3dccbf3e..05dd9417b9 100644 --- a/packages/client/lib/commands/RENAME.spec.ts +++ b/packages/client/lib/commands/RENAME.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RENAME from './RENAME'; +import { parseArgs } from './generic-transformers'; describe('RENAME', () => { it('transformArguments', () => { assert.deepEqual( - RENAME.transformArguments('source', 'destination'), + parseArgs(RENAME, 'source', 'destination'), ['RENAME', 'source', 'destination'] ); }); diff --git a/packages/client/lib/commands/RENAME.ts b/packages/client/lib/commands/RENAME.ts index 16e883d053..245851ca31 100644 --- a/packages/client/lib/commands/RENAME.ts +++ b/packages/client/lib/commands/RENAME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, newKey: RedisArgument) { - return ['RENAME', key, newKey]; + parseCommand(parser: CommandParser, key: RedisArgument, newKey: RedisArgument) { + parser.push('RENAME'); + parser.pushKeys([key, newKey]); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RENAMENX.spec.ts b/packages/client/lib/commands/RENAMENX.spec.ts index 5f83933e95..2367b45332 100644 --- a/packages/client/lib/commands/RENAMENX.spec.ts +++ b/packages/client/lib/commands/RENAMENX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RENAMENX from './RENAMENX'; +import { parseArgs } from './generic-transformers'; describe('RENAMENX', () => { it('transformArguments', () => { assert.deepEqual( - RENAMENX.transformArguments('source', 'destination'), + parseArgs(RENAMENX, 'source', 'destination'), ['RENAMENX', 'source', 'destination'] ); }); diff --git a/packages/client/lib/commands/RENAMENX.ts b/packages/client/lib/commands/RENAMENX.ts index 3a4f155d5a..0e8d4f73cf 100644 --- a/packages/client/lib/commands/RENAMENX.ts +++ b/packages/client/lib/commands/RENAMENX.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, newKey: RedisArgument) { - return ['RENAMENX', key, newKey]; + parseCommand(parser: CommandParser, key: RedisArgument, newKey: RedisArgument) { + parser.push('RENAMENX'); + parser.pushKeys([key, newKey]); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/REPLICAOF.spec.ts b/packages/client/lib/commands/REPLICAOF.spec.ts index 77dbe06045..1366863949 100644 --- a/packages/client/lib/commands/REPLICAOF.spec.ts +++ b/packages/client/lib/commands/REPLICAOF.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import REPLICAOF from './REPLICAOF'; +import { parseArgs } from './generic-transformers'; describe('REPLICAOF', () => { it('transformArguments', () => { assert.deepEqual( - REPLICAOF.transformArguments('host', 1), + parseArgs(REPLICAOF, 'host', 1), ['REPLICAOF', 'host', '1'] ); }); diff --git a/packages/client/lib/commands/REPLICAOF.ts b/packages/client/lib/commands/REPLICAOF.ts index 4e2f69f726..c4b09bc4fb 100644 --- a/packages/client/lib/commands/REPLICAOF.ts +++ b/packages/client/lib/commands/REPLICAOF.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(host: string, port: number) { - return ['REPLICAOF', host, port.toString()]; + parseCommand(parser: CommandParser, host: string, port: number) { + parser.push('REPLICAOF', host, port.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RESTORE-ASKING.spec.ts b/packages/client/lib/commands/RESTORE-ASKING.spec.ts index 855196b977..1258cf68e2 100644 --- a/packages/client/lib/commands/RESTORE-ASKING.spec.ts +++ b/packages/client/lib/commands/RESTORE-ASKING.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import RESTORE_ASKING from './RESTORE-ASKING'; +import { parseArgs } from './generic-transformers'; describe('RESTORE-ASKING', () => { it('transformArguments', () => { assert.deepEqual( - RESTORE_ASKING.transformArguments(), + parseArgs(RESTORE_ASKING), ['RESTORE-ASKING'] ); }); diff --git a/packages/client/lib/commands/RESTORE-ASKING.ts b/packages/client/lib/commands/RESTORE-ASKING.ts index 14f6dcbeab..e8de532b6a 100644 --- a/packages/client/lib/commands/RESTORE-ASKING.ts +++ b/packages/client/lib/commands/RESTORE-ASKING.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['RESTORE-ASKING']; + parseCommand(parser: CommandParser) { + parser.push('RESTORE-ASKING'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RESTORE.spec.ts b/packages/client/lib/commands/RESTORE.spec.ts index 6b814e7325..6083b2eb1a 100644 --- a/packages/client/lib/commands/RESTORE.spec.ts +++ b/packages/client/lib/commands/RESTORE.spec.ts @@ -2,19 +2,20 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import RESTORE from './RESTORE'; import { RESP_TYPES } from '../RESP/decoder'; +import { parseArgs } from './generic-transformers'; describe('RESTORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value'), + parseArgs(RESTORE, 'key', 0, 'value'), ['RESTORE', 'key', '0', 'value'] ); }); it('with REPLACE', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value', { + parseArgs(RESTORE, 'key', 0, 'value', { REPLACE: true }), ['RESTORE', 'key', '0', 'value', 'REPLACE'] @@ -23,7 +24,7 @@ describe('RESTORE', () => { it('with ABSTTL', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value', { + parseArgs(RESTORE, 'key', 0, 'value', { ABSTTL: true }), ['RESTORE', 'key', '0', 'value', 'ABSTTL'] @@ -32,7 +33,7 @@ describe('RESTORE', () => { it('with IDLETIME', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value', { + parseArgs(RESTORE, 'key', 0, 'value', { IDLETIME: 1 }), ['RESTORE', 'key', '0', 'value', 'IDLETIME', '1'] @@ -41,7 +42,7 @@ describe('RESTORE', () => { it('with FREQ', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value', { + parseArgs(RESTORE, 'key', 0, 'value', { FREQ: 1 }), ['RESTORE', 'key', '0', 'value', 'FREQ', '1'] @@ -50,7 +51,7 @@ describe('RESTORE', () => { it('with REPLACE, ABSTTL, IDLETIME and FREQ', () => { assert.deepEqual( - RESTORE.transformArguments('key', 0, 'value', { + parseArgs(RESTORE, 'key', 0, 'value', { REPLACE: true, ABSTTL: true, IDLETIME: 1, diff --git a/packages/client/lib/commands/RESTORE.ts b/packages/client/lib/commands/RESTORE.ts index b24c5b569f..49016c525b 100644 --- a/packages/client/lib/commands/RESTORE.ts +++ b/packages/client/lib/commands/RESTORE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export interface RestoreOptions { @@ -8,33 +9,33 @@ export interface RestoreOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, ttl: number, serializedValue: RedisArgument, options?: RestoreOptions ) { - const args = ['RESTORE', key, ttl.toString(), serializedValue]; + parser.push('RESTORE'); + parser.pushKey(key); + parser.push(ttl.toString(), serializedValue); if (options?.REPLACE) { - args.push('REPLACE'); + parser.push('REPLACE'); } if (options?.ABSTTL) { - args.push('ABSTTL'); + parser.push('ABSTTL'); } if (options?.IDLETIME) { - args.push('IDLETIME', options.IDLETIME.toString()); + parser.push('IDLETIME', options.IDLETIME.toString()); } if (options?.FREQ) { - args.push('FREQ', options.FREQ.toString()); + parser.push('FREQ', options.FREQ.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/ROLE.spec.ts b/packages/client/lib/commands/ROLE.spec.ts index c57ba5ba1f..09ce6ed342 100644 --- a/packages/client/lib/commands/ROLE.spec.ts +++ b/packages/client/lib/commands/ROLE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ROLE from './ROLE'; +import { parseArgs } from './generic-transformers'; describe('ROLE', () => { it('transformArguments', () => { assert.deepEqual( - ROLE.transformArguments(), + parseArgs(ROLE), ['ROLE'] ); }); diff --git a/packages/client/lib/commands/ROLE.ts b/packages/client/lib/commands/ROLE.ts index 7828e53fb6..f45bbad5c0 100644 --- a/packages/client/lib/commands/ROLE.ts +++ b/packages/client/lib/commands/ROLE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, NumberReply, ArrayReply, TuplesReply, UnwrapReply, Command } from '../RESP/types'; type MasterRole = [ @@ -22,10 +23,10 @@ type SentinelRole = [ type Role = TuplesReply; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['ROLE']; + parseCommand(parser: CommandParser) { + parser.push('ROLE'); }, transformReply(reply: UnwrapReply) { switch (reply[0] as unknown as UnwrapReply) { diff --git a/packages/client/lib/commands/RPOP.spec.ts b/packages/client/lib/commands/RPOP.spec.ts index 8ac5cb290f..844965eae1 100644 --- a/packages/client/lib/commands/RPOP.spec.ts +++ b/packages/client/lib/commands/RPOP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RPOP from './RPOP'; +import { parseArgs } from './generic-transformers'; describe('RPOP', () => { it('transformArguments', () => { assert.deepEqual( - RPOP.transformArguments('key'), + parseArgs(RPOP, 'key'), ['RPOP', 'key'] ); }); diff --git a/packages/client/lib/commands/RPOP.ts b/packages/client/lib/commands/RPOP.ts index f7d0b33d3a..4cc105c370 100644 --- a/packages/client/lib/commands/RPOP.ts +++ b/packages/client/lib/commands/RPOP.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument) { - return ['RPOP', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('RPOP'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RPOPLPUSH.spec.ts b/packages/client/lib/commands/RPOPLPUSH.spec.ts index 59458fc0aa..728d600bc9 100644 --- a/packages/client/lib/commands/RPOPLPUSH.spec.ts +++ b/packages/client/lib/commands/RPOPLPUSH.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RPOPLPUSH from './RPOPLPUSH'; +import { parseArgs } from './generic-transformers'; describe('RPOPLPUSH', () => { it('transformArguments', () => { assert.deepEqual( - RPOPLPUSH.transformArguments('source', 'destination'), + parseArgs(RPOPLPUSH, 'source', 'destination'), ['RPOPLPUSH', 'source', 'destination'] ); }); diff --git a/packages/client/lib/commands/RPOPLPUSH.ts b/packages/client/lib/commands/RPOPLPUSH.ts index 1a5e1cc59b..dcac047223 100644 --- a/packages/client/lib/commands/RPOPLPUSH.ts +++ b/packages/client/lib/commands/RPOPLPUSH.ts @@ -1,12 +1,10 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - source: RedisArgument, - destination: RedisArgument - ) { - return ['RPOPLPUSH', source, destination]; + parseCommand(parser: CommandParser, source: RedisArgument, destination: RedisArgument) { + parser.push('RPOPLPUSH'); + parser.pushKeys([source, destination]); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RPOP_COUNT.spec.ts b/packages/client/lib/commands/RPOP_COUNT.spec.ts index 14f1854b8b..e055d8655b 100644 --- a/packages/client/lib/commands/RPOP_COUNT.spec.ts +++ b/packages/client/lib/commands/RPOP_COUNT.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RPOP_COUNT from './RPOP_COUNT'; +import { parseArgs } from './generic-transformers'; describe('RPOP COUNT', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - RPOP_COUNT.transformArguments('key', 1), + parseArgs(RPOP_COUNT, 'key', 1), ['RPOP', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/RPOP_COUNT.ts b/packages/client/lib/commands/RPOP_COUNT.ts index b60dec6ab9..aff91c6a6f 100644 --- a/packages/client/lib/commands/RPOP_COUNT.ts +++ b/packages/client/lib/commands/RPOP_COUNT.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, count: number) { - return ['RPOP', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('RPOP'); + parser.pushKey(key); + parser.push(count.toString()); }, transformReply: undefined as unknown as () => ArrayReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RPUSH.spec.ts b/packages/client/lib/commands/RPUSH.spec.ts index 06078d7595..559fb7a274 100644 --- a/packages/client/lib/commands/RPUSH.spec.ts +++ b/packages/client/lib/commands/RPUSH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RPUSH from './RPUSH'; +import { parseArgs } from './generic-transformers'; describe('RPUSH', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - RPUSH.transformArguments('key', 'element'), + parseArgs(RPUSH, 'key', 'element'), ['RPUSH', 'key', 'element'] ); }); it('array', () => { assert.deepEqual( - RPUSH.transformArguments('key', ['1', '2']), + parseArgs(RPUSH, 'key', ['1', '2']), ['RPUSH', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/RPUSH.ts b/packages/client/lib/commands/RPUSH.ts index 4b04877738..b820aae690 100644 --- a/packages/client/lib/commands/RPUSH.ts +++ b/packages/client/lib/commands/RPUSH.ts @@ -1,13 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - element: RedisVariadicArgument - ) { - return pushVariadicArguments(['RPUSH', key], element); + parseCommand(parser: CommandParser, key: RedisArgument, element: RedisVariadicArgument) { + parser.push('RPUSH'); + parser.pushKey(key); + parser.pushVariadic(element); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/RPUSHX.spec.ts b/packages/client/lib/commands/RPUSHX.spec.ts index 5adaa8b263..b9fb660c5b 100644 --- a/packages/client/lib/commands/RPUSHX.spec.ts +++ b/packages/client/lib/commands/RPUSHX.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RPUSHX from './RPUSHX'; +import { parseArgs } from './generic-transformers'; describe('RPUSHX', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - RPUSHX.transformArguments('key', 'element'), + parseArgs(RPUSHX, 'key', 'element'), ['RPUSHX', 'key', 'element'] ); }); it('array', () => { assert.deepEqual( - RPUSHX.transformArguments('key', ['1', '2']), + parseArgs(RPUSHX, 'key', ['1', '2']), ['RPUSHX', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/RPUSHX.ts b/packages/client/lib/commands/RPUSHX.ts index 00b29624b0..243f717bb7 100644 --- a/packages/client/lib/commands/RPUSHX.ts +++ b/packages/client/lib/commands/RPUSHX.ts @@ -1,13 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - element: RedisVariadicArgument - ) { - return pushVariadicArguments(['RPUSHX', key], element); + parseCommand(parser: CommandParser, key: RedisArgument, element: RedisVariadicArgument) { + parser.push('RPUSHX'); + parser.pushKey(key); + parser.pushVariadic(element); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SADD.spec.ts b/packages/client/lib/commands/SADD.spec.ts index 77adc1c18c..179e8602ef 100644 --- a/packages/client/lib/commands/SADD.spec.ts +++ b/packages/client/lib/commands/SADD.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SADD from './SADD'; +import { parseArgs } from './generic-transformers'; describe('SADD', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SADD.transformArguments('key', 'member'), + parseArgs(SADD, 'key', 'member'), ['SADD', 'key', 'member'] ); }); it('array', () => { assert.deepEqual( - SADD.transformArguments('key', ['1', '2']), + parseArgs(SADD, 'key', ['1', '2']), ['SADD', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SADD.ts b/packages/client/lib/commands/SADD.ts index 2ff5e9263c..1fb0171d8d 100644 --- a/packages/client/lib/commands/SADD.ts +++ b/packages/client/lib/commands/SADD.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, members: RedisVariadicArgument) { - return pushVariadicArguments(['SADD', key], members); + parseCommand(parser: CommandParser, key: RedisArgument, members: RedisVariadicArgument) { + parser.push('SADD'); + parser.pushKey(key); + parser.pushVariadic(members); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SAVE.spec.ts b/packages/client/lib/commands/SAVE.spec.ts index 5c014da7ed..5f0074f749 100644 --- a/packages/client/lib/commands/SAVE.spec.ts +++ b/packages/client/lib/commands/SAVE.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import SAVE from './SAVE'; +import { parseArgs } from './generic-transformers'; describe('SAVE', () => { it('transformArguments', () => { assert.deepEqual( - SAVE.transformArguments(), + parseArgs(SAVE), ['SAVE'] ); }); diff --git a/packages/client/lib/commands/SAVE.ts b/packages/client/lib/commands/SAVE.ts index ee6cccd35a..ee78884083 100644 --- a/packages/client/lib/commands/SAVE.ts +++ b/packages/client/lib/commands/SAVE.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['SAVE']; + parseCommand(parser: CommandParser) { + parser.push('SAVE'); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SCAN.spec.ts b/packages/client/lib/commands/SCAN.spec.ts index f4dd865d11..2a32cbebf4 100644 --- a/packages/client/lib/commands/SCAN.spec.ts +++ b/packages/client/lib/commands/SCAN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import SCAN from './SCAN'; describe('SCAN', () => { describe('transformArguments', () => { it('cusror only', () => { assert.deepEqual( - SCAN.transformArguments('0'), + parseArgs(SCAN, '0'), ['SCAN', '0'] ); }); it('with MATCH', () => { assert.deepEqual( - SCAN.transformArguments('0', { + parseArgs(SCAN, '0', { MATCH: 'pattern' }), ['SCAN', '0', 'MATCH', 'pattern'] @@ -22,7 +23,7 @@ describe('SCAN', () => { it('with COUNT', () => { assert.deepEqual( - SCAN.transformArguments('0', { + parseArgs(SCAN, '0', { COUNT: 1 }), ['SCAN', '0', 'COUNT', '1'] @@ -31,7 +32,7 @@ describe('SCAN', () => { it('with TYPE', () => { assert.deepEqual( - SCAN.transformArguments('0', { + parseArgs(SCAN, '0', { TYPE: 'stream' }), ['SCAN', '0', 'TYPE', 'stream'] @@ -40,7 +41,7 @@ describe('SCAN', () => { it('with MATCH & COUNT & TYPE', () => { assert.deepEqual( - SCAN.transformArguments('0', { + parseArgs(SCAN, '0', { MATCH: 'pattern', COUNT: 1, TYPE: 'stream' diff --git a/packages/client/lib/commands/SCAN.ts b/packages/client/lib/commands/SCAN.ts index 13f5444044..2d6e4c3525 100644 --- a/packages/client/lib/commands/SCAN.ts +++ b/packages/client/lib/commands/SCAN.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, CommandArguments, BlobStringReply, ArrayReply, Command } from '../RESP/types'; export interface ScanCommonOptions { @@ -5,6 +6,21 @@ export interface ScanCommonOptions { COUNT?: number; } +export function parseScanArguments( + parser: CommandParser, + cursor: RedisArgument, + options?: ScanOptions +) { + parser.push(cursor); + if (options?.MATCH) { + parser.push('MATCH', options.MATCH); + } + + if (options?.COUNT) { + parser.push('COUNT', options.COUNT.toString()); + } +} + export function pushScanArguments( args: CommandArguments, cursor: RedisArgument, @@ -28,16 +44,15 @@ export interface ScanOptions extends ScanCommonOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(cursor: RedisArgument, options?: ScanOptions) { - const args = pushScanArguments(['SCAN'], cursor, options); + parseCommand(parser: CommandParser, cursor: RedisArgument, options?: ScanOptions) { + parser.push('SCAN'); + parseScanArguments(parser, cursor, options); if (options?.TYPE) { - args.push('TYPE', options.TYPE); + parser.push('TYPE', options.TYPE); } - - return args; }, transformReply([cursor, keys]: [BlobStringReply, ArrayReply]) { return { diff --git a/packages/client/lib/commands/SCARD.spec.ts b/packages/client/lib/commands/SCARD.spec.ts index 5029f340d9..5343458383 100644 --- a/packages/client/lib/commands/SCARD.spec.ts +++ b/packages/client/lib/commands/SCARD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import SCARD from './SCARD'; describe('SCARD', () => { it('transformArguments', () => { assert.deepEqual( - SCARD.transformArguments('key'), + parseArgs(SCARD, 'key'), ['SCARD', 'key'] ); }); diff --git a/packages/client/lib/commands/SCARD.ts b/packages/client/lib/commands/SCARD.ts index c13d042ba6..61d4792d99 100644 --- a/packages/client/lib/commands/SCARD.ts +++ b/packages/client/lib/commands/SCARD.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['SCARD', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('SCARD'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SCRIPT_DEBUG.spec.ts b/packages/client/lib/commands/SCRIPT_DEBUG.spec.ts index 4e07f2c250..c98143a341 100644 --- a/packages/client/lib/commands/SCRIPT_DEBUG.spec.ts +++ b/packages/client/lib/commands/SCRIPT_DEBUG.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SCRIPT_DEBUG from './SCRIPT_DEBUG'; +import { parseArgs } from './generic-transformers'; describe('SCRIPT DEBUG', () => { it('transformArguments', () => { assert.deepEqual( - SCRIPT_DEBUG.transformArguments('NO'), + parseArgs(SCRIPT_DEBUG, 'NO'), ['SCRIPT', 'DEBUG', 'NO'] ); }); diff --git a/packages/client/lib/commands/SCRIPT_DEBUG.ts b/packages/client/lib/commands/SCRIPT_DEBUG.ts index 3c49ff709d..b0d3079068 100644 --- a/packages/client/lib/commands/SCRIPT_DEBUG.ts +++ b/packages/client/lib/commands/SCRIPT_DEBUG.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(mode: 'YES' | 'SYNC' | 'NO') { - return ['SCRIPT', 'DEBUG', mode]; + parseCommand(parser: CommandParser, mode: 'YES' | 'SYNC' | 'NO') { + parser.push('SCRIPT', 'DEBUG', mode); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/SCRIPT_EXISTS.spec.ts b/packages/client/lib/commands/SCRIPT_EXISTS.spec.ts index 8afdbb5f58..cf65156c72 100644 --- a/packages/client/lib/commands/SCRIPT_EXISTS.spec.ts +++ b/packages/client/lib/commands/SCRIPT_EXISTS.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SCRIPT_EXISTS from './SCRIPT_EXISTS'; +import { parseArgs } from './generic-transformers'; describe('SCRIPT EXISTS', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SCRIPT_EXISTS.transformArguments('sha1'), + parseArgs(SCRIPT_EXISTS, 'sha1'), ['SCRIPT', 'EXISTS', 'sha1'] ); }); it('array', () => { assert.deepEqual( - SCRIPT_EXISTS.transformArguments(['1', '2']), + parseArgs(SCRIPT_EXISTS, ['1', '2']), ['SCRIPT', 'EXISTS', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SCRIPT_EXISTS.ts b/packages/client/lib/commands/SCRIPT_EXISTS.ts index ab0a293d8d..b0f6cbe227 100644 --- a/packages/client/lib/commands/SCRIPT_EXISTS.ts +++ b/packages/client/lib/commands/SCRIPT_EXISTS.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(sha1: RedisVariadicArgument) { - return pushVariadicArguments(['SCRIPT', 'EXISTS'], sha1); + parseCommand(parser: CommandParser, sha1: RedisVariadicArgument) { + parser.push('SCRIPT', 'EXISTS'); + parser.pushVariadic(sha1); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SCRIPT_FLUSH.spec.ts b/packages/client/lib/commands/SCRIPT_FLUSH.spec.ts index ccc14ecc28..c51efd1a36 100644 --- a/packages/client/lib/commands/SCRIPT_FLUSH.spec.ts +++ b/packages/client/lib/commands/SCRIPT_FLUSH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SCRIPT_FLUSH from './SCRIPT_FLUSH'; +import { parseArgs } from './generic-transformers'; describe('SCRIPT FLUSH', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SCRIPT_FLUSH.transformArguments(), + parseArgs(SCRIPT_FLUSH), ['SCRIPT', 'FLUSH'] ); }); it('with mode', () => { assert.deepEqual( - SCRIPT_FLUSH.transformArguments('SYNC'), + parseArgs(SCRIPT_FLUSH, 'SYNC'), ['SCRIPT', 'FLUSH', 'SYNC'] ); }); diff --git a/packages/client/lib/commands/SCRIPT_FLUSH.ts b/packages/client/lib/commands/SCRIPT_FLUSH.ts index f542639562..1e05a619ba 100644 --- a/packages/client/lib/commands/SCRIPT_FLUSH.ts +++ b/packages/client/lib/commands/SCRIPT_FLUSH.ts @@ -1,16 +1,15 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(mode?: 'ASYNC' | 'SYNC') { - const args = ['SCRIPT', 'FLUSH']; + parseCommand(parser: CommandParser, mode?: 'ASYNC' | 'SYNC') { + parser.push('SCRIPT', 'FLUSH'); if (mode) { - args.push(mode); + parser.push(mode); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/SCRIPT_KILL.spec.ts b/packages/client/lib/commands/SCRIPT_KILL.spec.ts index 1499c97ac0..7186efd54c 100644 --- a/packages/client/lib/commands/SCRIPT_KILL.spec.ts +++ b/packages/client/lib/commands/SCRIPT_KILL.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import SCRIPT_KILL from './SCRIPT_KILL'; +import { parseArgs } from './generic-transformers'; describe('SCRIPT KILL', () => { it('transformArguments', () => { assert.deepEqual( - SCRIPT_KILL.transformArguments(), + parseArgs(SCRIPT_KILL), ['SCRIPT', 'KILL'] ); }); diff --git a/packages/client/lib/commands/SCRIPT_KILL.ts b/packages/client/lib/commands/SCRIPT_KILL.ts index ac025b788b..2695350623 100644 --- a/packages/client/lib/commands/SCRIPT_KILL.ts +++ b/packages/client/lib/commands/SCRIPT_KILL.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['SCRIPT', 'KILL']; + parseCommand(parser: CommandParser) { + parser.push('SCRIPT', 'KILL'); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/SCRIPT_LOAD.spec.ts b/packages/client/lib/commands/SCRIPT_LOAD.spec.ts index d964859d2f..b0df9887e1 100644 --- a/packages/client/lib/commands/SCRIPT_LOAD.spec.ts +++ b/packages/client/lib/commands/SCRIPT_LOAD.spec.ts @@ -2,6 +2,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SCRIPT_LOAD from './SCRIPT_LOAD'; import { scriptSha1 } from '../lua-script'; +import { parseArgs } from './generic-transformers'; describe('SCRIPT LOAD', () => { const SCRIPT = 'return 1;', @@ -9,7 +10,7 @@ describe('SCRIPT LOAD', () => { it('transformArguments', () => { assert.deepEqual( - SCRIPT_LOAD.transformArguments(SCRIPT), + parseArgs(SCRIPT_LOAD, SCRIPT), ['SCRIPT', 'LOAD', SCRIPT] ); }); diff --git a/packages/client/lib/commands/SCRIPT_LOAD.ts b/packages/client/lib/commands/SCRIPT_LOAD.ts index 90028b13a5..58f7c00dfc 100644 --- a/packages/client/lib/commands/SCRIPT_LOAD.ts +++ b/packages/client/lib/commands/SCRIPT_LOAD.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command, RedisArgument } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(script: RedisArgument) { - return ['SCRIPT', 'LOAD', script]; + parseCommand(parser: CommandParser, script: RedisArgument) { + parser.push('SCRIPT', 'LOAD', script); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SDIFF.spec.ts b/packages/client/lib/commands/SDIFF.spec.ts index 83ac6dc1da..a943a80688 100644 --- a/packages/client/lib/commands/SDIFF.spec.ts +++ b/packages/client/lib/commands/SDIFF.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SDIFF from './SDIFF'; +import { parseArgs } from './generic-transformers'; describe('SDIFF', () => { - describe('transformArguments', () => { + describe('processCommand', () => { it('string', () => { assert.deepEqual( - SDIFF.transformArguments('key'), + parseArgs(SDIFF, 'key'), ['SDIFF', 'key'] ); }); it('array', () => { assert.deepEqual( - SDIFF.transformArguments(['1', '2']), + parseArgs(SDIFF, ['1', '2']), ['SDIFF', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SDIFF.ts b/packages/client/lib/commands/SDIFF.ts index 918cbf7fa1..bd78edc93d 100644 --- a/packages/client/lib/commands/SDIFF.ts +++ b/packages/client/lib/commands/SDIFF.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArguments(['SDIFF'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('SDIFF'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SDIFFSTORE.spec.ts b/packages/client/lib/commands/SDIFFSTORE.spec.ts index 613a9eb590..43213adfbb 100644 --- a/packages/client/lib/commands/SDIFFSTORE.spec.ts +++ b/packages/client/lib/commands/SDIFFSTORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SDIFFSTORE from './SDIFFSTORE'; +import { parseArgs } from './generic-transformers'; describe('SDIFFSTORE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SDIFFSTORE.transformArguments('destination', 'key'), + parseArgs(SDIFFSTORE, 'destination', 'key'), ['SDIFFSTORE', 'destination', 'key'] ); }); it('array', () => { assert.deepEqual( - SDIFFSTORE.transformArguments('destination', ['1', '2']), + parseArgs(SDIFFSTORE, 'destination', ['1', '2']), ['SDIFFSTORE', 'destination', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SDIFFSTORE.ts b/packages/client/lib/commands/SDIFFSTORE.ts index 15f0ccb499..6da2795d8f 100644 --- a/packages/client/lib/commands/SDIFFSTORE.ts +++ b/packages/client/lib/commands/SDIFFSTORE.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(destination: RedisArgument, keys: RedisVariadicArgument) { - return pushVariadicArguments(['SDIFFSTORE', destination], keys); + parseCommand(parser: CommandParser, destination: RedisArgument, keys: RedisVariadicArgument) { + parser.push('SDIFFSTORE'); + parser.pushKey(destination); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SET.spec.ts b/packages/client/lib/commands/SET.spec.ts index 4364eb7391..b8aa57fe77 100644 --- a/packages/client/lib/commands/SET.spec.ts +++ b/packages/client/lib/commands/SET.spec.ts @@ -1,20 +1,21 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SET from './SET'; +import { parseArgs } from './generic-transformers'; describe('SET', () => { describe('transformArguments', () => { describe('value', () => { it('string', () => { assert.deepEqual( - SET.transformArguments('key', 'value'), + parseArgs(SET, 'key', 'value'), ['SET', 'key', 'value'] ); }); it('number', () => { assert.deepEqual( - SET.transformArguments('key', 0), + parseArgs(SET, 'key', 0), ['SET', 'key', '0'] ); }); @@ -23,7 +24,7 @@ describe('SET', () => { describe('expiration', () => { it('\'KEEPTTL\'', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { expiration: 'KEEPTTL' }), ['SET', 'key', 'value', 'KEEPTTL'] @@ -32,7 +33,7 @@ describe('SET', () => { it('{ type: \'KEEPTTL\' }', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { expiration: { type: 'KEEPTTL' } @@ -43,7 +44,7 @@ describe('SET', () => { it('{ type: \'EX\' }', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { expiration: { type: 'EX', value: 0 @@ -55,7 +56,7 @@ describe('SET', () => { it('with EX (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { EX: 0 }), ['SET', 'key', 'value', 'EX', '0'] @@ -64,7 +65,7 @@ describe('SET', () => { it('with PX (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { PX: 0 }), ['SET', 'key', 'value', 'PX', '0'] @@ -73,7 +74,7 @@ describe('SET', () => { it('with EXAT (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { EXAT: 0 }), ['SET', 'key', 'value', 'EXAT', '0'] @@ -82,7 +83,7 @@ describe('SET', () => { it('with PXAT (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { PXAT: 0 }), ['SET', 'key', 'value', 'PXAT', '0'] @@ -91,7 +92,7 @@ describe('SET', () => { it('with KEEPTTL (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { KEEPTTL: true }), ['SET', 'key', 'value', 'KEEPTTL'] @@ -102,7 +103,7 @@ describe('SET', () => { describe('condition', () => { it('with condition', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { condition: 'NX' }), ['SET', 'key', 'value', 'NX'] @@ -111,7 +112,7 @@ describe('SET', () => { it('with NX (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { NX: true }), ['SET', 'key', 'value', 'NX'] @@ -120,7 +121,7 @@ describe('SET', () => { it('with XX (backwards compatibility)', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { XX: true }), ['SET', 'key', 'value', 'XX'] @@ -130,7 +131,7 @@ describe('SET', () => { it('with GET', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { GET: true }), ['SET', 'key', 'value', 'GET'] @@ -139,7 +140,7 @@ describe('SET', () => { it('with expiration, condition, GET', () => { assert.deepEqual( - SET.transformArguments('key', 'value', { + parseArgs(SET, 'key', 'value', { expiration: { type: 'EX', value: 0 diff --git a/packages/client/lib/commands/SET.ts b/packages/client/lib/commands/SET.ts index cede62e705..d2d13c874c 100644 --- a/packages/client/lib/commands/SET.ts +++ b/packages/client/lib/commands/SET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, BlobStringReply, NullReply, Command } from '../RESP/types'; export interface SetOptions { @@ -42,50 +43,45 @@ export interface SetOptions { } export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, value: RedisArgument | number, options?: SetOptions) { - const args = [ - 'SET', - key, - typeof value === 'number' ? value.toString() : value - ]; + parseCommand(parser: CommandParser, key: RedisArgument, value: RedisArgument | number, options?: SetOptions) { + parser.push('SET'); + parser.pushKey(key); + parser.push(typeof value === 'number' ? value.toString() : value); if (options?.expiration) { if (typeof options.expiration === 'string') { - args.push(options.expiration); + parser.push(options.expiration); } else if (options.expiration.type === 'KEEPTTL') { - args.push('KEEPTTL'); + parser.push('KEEPTTL'); } else { - args.push( + parser.push( options.expiration.type, options.expiration.value.toString() ); } } else if (options?.EX !== undefined) { - args.push('EX', options.EX.toString()); + parser.push('EX', options.EX.toString()); } else if (options?.PX !== undefined) { - args.push('PX', options.PX.toString()); + parser.push('PX', options.PX.toString()); } else if (options?.EXAT !== undefined) { - args.push('EXAT', options.EXAT.toString()); + parser.push('EXAT', options.EXAT.toString()); } else if (options?.PXAT !== undefined) { - args.push('PXAT', options.PXAT.toString()); + parser.push('PXAT', options.PXAT.toString()); } else if (options?.KEEPTTL) { - args.push('KEEPTTL'); + parser.push('KEEPTTL'); } if (options?.condition) { - args.push(options.condition); + parser.push(options.condition); } else if (options?.NX) { - args.push('NX'); + parser.push('NX'); } else if (options?.XX) { - args.push('XX'); + parser.push('XX'); } if (options?.GET) { - args.push('GET'); + parser.push('GET'); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> | BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SETBIT.spec.ts b/packages/client/lib/commands/SETBIT.spec.ts index e4470bb152..1eedcc6995 100644 --- a/packages/client/lib/commands/SETBIT.spec.ts +++ b/packages/client/lib/commands/SETBIT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SETBIT from './SETBIT'; +import { parseArgs } from './generic-transformers'; describe('SETBIT', () => { it('transformArguments', () => { assert.deepEqual( - SETBIT.transformArguments('key', 0, 1), + parseArgs(SETBIT, 'key', 0, 1), ['SETBIT', 'key', '0', '1'] ); }); diff --git a/packages/client/lib/commands/SETBIT.ts b/packages/client/lib/commands/SETBIT.ts index 5b3ec6173d..5cd2926007 100644 --- a/packages/client/lib/commands/SETBIT.ts +++ b/packages/client/lib/commands/SETBIT.ts @@ -1,15 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { BitValue } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - key: RedisArgument, - offset: number, - value: BitValue - ) { - return ['SETBIT', key, offset.toString(), value.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, offset: number, value: BitValue) { + parser.push('SETBIT'); + parser.pushKey(key); + parser.push(offset.toString(), value.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SETEX.spec.ts b/packages/client/lib/commands/SETEX.spec.ts index 00f204cc71..7bc934ccd6 100644 --- a/packages/client/lib/commands/SETEX.spec.ts +++ b/packages/client/lib/commands/SETEX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SETEX from './SETEX'; +import { parseArgs } from './generic-transformers'; describe('SETEX', () => { it('transformArguments', () => { assert.deepEqual( - SETEX.transformArguments('key', 1, 'value'), + parseArgs(SETEX, 'key', 1, 'value'), ['SETEX', 'key', '1', 'value'] ); }); diff --git a/packages/client/lib/commands/SETEX.ts b/packages/client/lib/commands/SETEX.ts index bbd77e5d99..5e58b58997 100644 --- a/packages/client/lib/commands/SETEX.ts +++ b/packages/client/lib/commands/SETEX.ts @@ -1,18 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - seconds: number, - value: RedisArgument - ) { - return [ - 'SETEX', - key, - seconds.toString(), - value - ]; + parseCommand(parser: CommandParser, key: RedisArgument, seconds: number, value: RedisArgument) { + parser.push('SETEX'); + parser.pushKey(key); + parser.push(seconds.toString(), value); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/SETNX .spec.ts b/packages/client/lib/commands/SETNX .spec.ts index 5cfca29ba6..81a5af3d41 100644 --- a/packages/client/lib/commands/SETNX .spec.ts +++ b/packages/client/lib/commands/SETNX .spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SETNX from './SETNX'; +import { parseArgs } from './generic-transformers'; describe('SETNX', () => { it('transformArguments', () => { assert.deepEqual( - SETNX.transformArguments('key', 'value'), + parseArgs(SETNX, 'key', 'value'), ['SETNX', 'key', 'value'] ); }); diff --git a/packages/client/lib/commands/SETNX.ts b/packages/client/lib/commands/SETNX.ts index 0940efad69..ae60067c28 100644 --- a/packages/client/lib/commands/SETNX.ts +++ b/packages/client/lib/commands/SETNX.ts @@ -1,9 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments(key: RedisArgument, value: RedisArgument) { - return ['SETNX', key, value]; + parseCommand(parser: CommandParser, key: RedisArgument, value: RedisArgument) { + parser.push('SETNX'); + parser.pushKey(key); + parser.push(value); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SETRANGE.spec.ts b/packages/client/lib/commands/SETRANGE.spec.ts index 01d3545a35..acdab5bcd3 100644 --- a/packages/client/lib/commands/SETRANGE.spec.ts +++ b/packages/client/lib/commands/SETRANGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SETRANGE from './SETRANGE'; +import { parseArgs } from './generic-transformers'; describe('SETRANGE', () => { it('transformArguments', () => { assert.deepEqual( - SETRANGE.transformArguments('key', 0, 'value'), + parseArgs(SETRANGE, 'key', 0, 'value'), ['SETRANGE', 'key', '0', 'value'] ); }); diff --git a/packages/client/lib/commands/SETRANGE.ts b/packages/client/lib/commands/SETRANGE.ts index 1951a82c07..42f4ca0111 100644 --- a/packages/client/lib/commands/SETRANGE.ts +++ b/packages/client/lib/commands/SETRANGE.ts @@ -1,18 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( - key: RedisArgument, - offset: number, - value: RedisArgument - ) { - return [ - 'SETRANGE', - key, - offset.toString(), - value - ]; + parseCommand(parser: CommandParser, key: RedisArgument, offset: number, value: RedisArgument) { + parser.push('SETRANGE'); + parser.pushKey(key); + parser.push(offset.toString(), value); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SHUTDOWN.spec.ts b/packages/client/lib/commands/SHUTDOWN.spec.ts index 7dd46a5d53..9c4ca852ad 100644 --- a/packages/client/lib/commands/SHUTDOWN.spec.ts +++ b/packages/client/lib/commands/SHUTDOWN.spec.ts @@ -1,18 +1,19 @@ import { strict as assert } from 'node:assert'; import SHUTDOWN from './SHUTDOWN'; +import { parseArgs } from './generic-transformers'; describe('SHUTDOWN', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SHUTDOWN.transformArguments(), + parseArgs(SHUTDOWN), ['SHUTDOWN'] ); }); it('with mode', () => { assert.deepEqual( - SHUTDOWN.transformArguments({ + parseArgs(SHUTDOWN, { mode: 'NOSAVE' }), ['SHUTDOWN', 'NOSAVE'] @@ -21,7 +22,7 @@ describe('SHUTDOWN', () => { it('with NOW', () => { assert.deepEqual( - SHUTDOWN.transformArguments({ + parseArgs(SHUTDOWN, { NOW: true }), ['SHUTDOWN', 'NOW'] @@ -30,7 +31,7 @@ describe('SHUTDOWN', () => { it('with FORCE', () => { assert.deepEqual( - SHUTDOWN.transformArguments({ + parseArgs(SHUTDOWN, { FORCE: true }), ['SHUTDOWN', 'FORCE'] @@ -39,7 +40,7 @@ describe('SHUTDOWN', () => { it('with ABORT', () => { assert.deepEqual( - SHUTDOWN.transformArguments({ + parseArgs(SHUTDOWN, { ABORT: true }), ['SHUTDOWN', 'ABORT'] diff --git a/packages/client/lib/commands/SHUTDOWN.ts b/packages/client/lib/commands/SHUTDOWN.ts index e0f3d08ce8..33fb3e7730 100644 --- a/packages/client/lib/commands/SHUTDOWN.ts +++ b/packages/client/lib/commands/SHUTDOWN.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export interface ShutdownOptions { @@ -8,28 +9,26 @@ export interface ShutdownOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(options?: ShutdownOptions) { - const args = ['SHUTDOWN'] + parseCommand(parser: CommandParser, options?: ShutdownOptions) { + parser.push('SHUTDOWN'); if (options?.mode) { - args.push(options.mode); + parser.push(options.mode); } if (options?.NOW) { - args.push('NOW'); + parser.push('NOW'); } if (options?.FORCE) { - args.push('FORCE'); + parser.push('FORCE'); } if (options?.ABORT) { - args.push('ABORT'); + parser.push('ABORT'); } - - return args; }, transformReply: undefined as unknown as () => void | SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SINTER.spec.ts b/packages/client/lib/commands/SINTER.spec.ts index 5b66fdd3f8..6ca7b959ca 100644 --- a/packages/client/lib/commands/SINTER.spec.ts +++ b/packages/client/lib/commands/SINTER.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SINTER from './SINTER'; +import { parseArgs } from './generic-transformers'; describe('SINTER', () => { - describe('transformArguments', () => { + describe('processCommand', () => { it('string', () => { assert.deepEqual( - SINTER.transformArguments('key'), + parseArgs(SINTER, 'key'), ['SINTER', 'key'] ); }); it('array', () => { assert.deepEqual( - SINTER.transformArguments(['1', '2']), + parseArgs(SINTER, ['1', '2']), ['SINTER', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SINTER.ts b/packages/client/lib/commands/SINTER.ts index f3f27de2e3..19ecdbb41c 100644 --- a/packages/client/lib/commands/SINTER.ts +++ b/packages/client/lib/commands/SINTER.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArguments(['SINTER'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('SINTER'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SINTERCARD.spec.ts b/packages/client/lib/commands/SINTERCARD.spec.ts index cddb886088..51aed13415 100644 --- a/packages/client/lib/commands/SINTERCARD.spec.ts +++ b/packages/client/lib/commands/SINTERCARD.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SINTERCARD from './SINTERCARD'; +import { parseArgs } from './generic-transformers'; describe('SINTERCARD', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,21 +9,21 @@ describe('SINTERCARD', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SINTERCARD.transformArguments(['1', '2']), + parseArgs(SINTERCARD, ['1', '2']), ['SINTERCARD', '2', '1', '2'] ); }); it('with limit (backwards compatibility)', () => { assert.deepEqual( - SINTERCARD.transformArguments(['1', '2'], 1), + parseArgs(SINTERCARD, ['1', '2'], 1), ['SINTERCARD', '2', '1', '2', 'LIMIT', '1'] ); }); it('with LIMIT', () => { assert.deepEqual( - SINTERCARD.transformArguments(['1', '2'], { + parseArgs(SINTERCARD, ['1', '2'], { LIMIT: 1 }), ['SINTERCARD', '2', '1', '2', 'LIMIT', '1'] diff --git a/packages/client/lib/commands/SINTERCARD.ts b/packages/client/lib/commands/SINTERCARD.ts index 626bc1048c..cb9e7d3be3 100644 --- a/packages/client/lib/commands/SINTERCARD.ts +++ b/packages/client/lib/commands/SINTERCARD.ts @@ -1,26 +1,23 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export interface SInterCardOptions { LIMIT?: number; } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( - keys: RedisVariadicArgument, - options?: SInterCardOptions | number // `number` for backwards compatibility - ) { - const args = pushVariadicArgument(['SINTERCARD'], keys); + // option `number` for backwards compatibility + parseCommand(parser: CommandParser, keys: RedisVariadicArgument, options?: SInterCardOptions | number) { + parser.push('SINTERCARD'); + parser.pushKeysLength(keys); if (typeof options === 'number') { // backwards compatibility - args.push('LIMIT', options.toString()); + parser.push('LIMIT', options.toString()); } else if (options?.LIMIT !== undefined) { - args.push('LIMIT', options.LIMIT.toString()); + parser.push('LIMIT', options.LIMIT.toString()); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SINTERSTORE.spec.ts b/packages/client/lib/commands/SINTERSTORE.spec.ts index 05416742ee..83302a5c82 100644 --- a/packages/client/lib/commands/SINTERSTORE.spec.ts +++ b/packages/client/lib/commands/SINTERSTORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SINTERSTORE from './SINTERSTORE'; +import { parseArgs } from './generic-transformers'; describe('SINTERSTORE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SINTERSTORE.transformArguments('destination', 'key'), + parseArgs(SINTERSTORE, 'destination', 'key'), ['SINTERSTORE', 'destination', 'key'] ); }); it('array', () => { assert.deepEqual( - SINTERSTORE.transformArguments('destination', ['1', '2']), + parseArgs(SINTERSTORE, 'destination', ['1', '2']), ['SINTERSTORE', 'destination', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SINTERSTORE.ts b/packages/client/lib/commands/SINTERSTORE.ts index 744e0b1845..06db0af9cb 100644 --- a/packages/client/lib/commands/SINTERSTORE.ts +++ b/packages/client/lib/commands/SINTERSTORE.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - destination: RedisArgument, - keys: RedisVariadicArgument - ) { - return pushVariadicArguments(['SINTERSTORE', destination], keys); + parseCommand(parser: CommandParser, destination: RedisArgument, keys: RedisVariadicArgument) { + parser.push('SINTERSTORE'); + parser.pushKey(destination) + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SISMEMBER.spec.ts b/packages/client/lib/commands/SISMEMBER.spec.ts index 0c1b92614c..4796475c52 100644 --- a/packages/client/lib/commands/SISMEMBER.spec.ts +++ b/packages/client/lib/commands/SISMEMBER.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SISMEMBER from './SISMEMBER'; +import { parseArgs } from './generic-transformers'; describe('SISMEMBER', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - SISMEMBER.transformArguments('key', 'member'), + parseArgs(SISMEMBER, 'key', 'member'), ['SISMEMBER', 'key', 'member'] ); }); diff --git a/packages/client/lib/commands/SISMEMBER.ts b/packages/client/lib/commands/SISMEMBER.ts index 0687d19de3..6192ca2605 100644 --- a/packages/client/lib/commands/SISMEMBER.ts +++ b/packages/client/lib/commands/SISMEMBER.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, member: RedisArgument) { - return ['SISMEMBER', key, member]; + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisArgument) { + parser.push('SISMEMBER'); + parser.pushKey(key); + parser.push(member); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SMEMBERS.spec.ts b/packages/client/lib/commands/SMEMBERS.spec.ts index 016b01ff74..6e2582e5ab 100644 --- a/packages/client/lib/commands/SMEMBERS.spec.ts +++ b/packages/client/lib/commands/SMEMBERS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SMEMBERS from './SMEMBERS'; +import { parseArgs } from './generic-transformers'; describe('SMEMBERS', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - SMEMBERS.transformArguments('key'), + parseArgs(SMEMBERS, 'key'), ['SMEMBERS', 'key'] ); }); diff --git a/packages/client/lib/commands/SMEMBERS.ts b/packages/client/lib/commands/SMEMBERS.ts index 391c83af6c..6d018e999f 100644 --- a/packages/client/lib/commands/SMEMBERS.ts +++ b/packages/client/lib/commands/SMEMBERS.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, SetReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['SMEMBERS', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('SMEMBERS'); + parser.pushKey(key); }, transformReply: { 2: undefined as unknown as () => ArrayReply, diff --git a/packages/client/lib/commands/SMISMEMBER.spec.ts b/packages/client/lib/commands/SMISMEMBER.spec.ts index 273ab05dd7..deff691236 100644 --- a/packages/client/lib/commands/SMISMEMBER.spec.ts +++ b/packages/client/lib/commands/SMISMEMBER.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SMISMEMBER from './SMISMEMBER'; +import { parseArgs } from './generic-transformers'; describe('SMISMEMBER', () => { testUtils.isVersionGreaterThanHook([6, 2]); - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - SMISMEMBER.transformArguments('key', ['1', '2']), + parseArgs(SMISMEMBER, 'key', ['1', '2']), ['SMISMEMBER', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SMISMEMBER.ts b/packages/client/lib/commands/SMISMEMBER.ts index bdf48d45ab..f0f3a143c7 100644 --- a/packages/client/lib/commands/SMISMEMBER.ts +++ b/packages/client/lib/commands/SMISMEMBER.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, members: Array) { - return ['SMISMEMBER', key, ...members]; + parseCommand(parser: CommandParser, key: RedisArgument, members: Array) { + parser.push('SMISMEMBER'); + parser.pushKey(key); + parser.pushVariadic(members); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SMOVE.spec.ts b/packages/client/lib/commands/SMOVE.spec.ts index 7ff2f773a7..c68a6e4191 100644 --- a/packages/client/lib/commands/SMOVE.spec.ts +++ b/packages/client/lib/commands/SMOVE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SMOVE from './SMOVE'; +import { parseArgs } from './generic-transformers'; describe('SMOVE', () => { it('transformArguments', () => { assert.deepEqual( - SMOVE.transformArguments('source', 'destination', 'member'), + parseArgs(SMOVE, 'source', 'destination', 'member'), ['SMOVE', 'source', 'destination', 'member'] ); }); diff --git a/packages/client/lib/commands/SMOVE.ts b/packages/client/lib/commands/SMOVE.ts index 183b363fb9..d87eeefdfb 100644 --- a/packages/client/lib/commands/SMOVE.ts +++ b/packages/client/lib/commands/SMOVE.ts @@ -1,14 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - source: RedisArgument, - destination: RedisArgument, - member: RedisArgument - ) { - return ['SMOVE', source, destination, member]; + parseCommand(parser: CommandParser, source: RedisArgument, destination: RedisArgument, member: RedisArgument) { + parser.push('SMOVE'); + parser.pushKeys([source, destination]); + parser.push(member); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SORT.spec.ts b/packages/client/lib/commands/SORT.spec.ts index 4fce811375..330b321a1b 100644 --- a/packages/client/lib/commands/SORT.spec.ts +++ b/packages/client/lib/commands/SORT.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SORT from './SORT'; +import { parseArgs } from './generic-transformers'; describe('SORT', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SORT.transformArguments('key'), + parseArgs(SORT, 'key'), ['SORT', 'key'] ); }); it('with BY', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { BY: 'pattern' }), ['SORT', 'key', 'BY', 'pattern'] @@ -22,7 +23,7 @@ describe('SORT', () => { it('with LIMIT', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { LIMIT: { offset: 0, count: 1 @@ -35,7 +36,7 @@ describe('SORT', () => { describe('with GET', () => { it('string', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { GET: 'pattern' }), ['SORT', 'key', 'GET', 'pattern'] @@ -44,7 +45,7 @@ describe('SORT', () => { it('array', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { GET: ['1', '2'] }), ['SORT', 'key', 'GET', '1', 'GET', '2'] @@ -54,7 +55,7 @@ describe('SORT', () => { it('with DIRECTION', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { DIRECTION: 'ASC' }), ['SORT', 'key', 'ASC'] @@ -63,7 +64,7 @@ describe('SORT', () => { it('with ALPHA', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { ALPHA: true }), ['SORT', 'key', 'ALPHA'] @@ -72,7 +73,7 @@ describe('SORT', () => { it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => { assert.deepEqual( - SORT.transformArguments('key', { + parseArgs(SORT, 'key', { BY: 'pattern', LIMIT: { offset: 0, diff --git a/packages/client/lib/commands/SORT.ts b/packages/client/lib/commands/SORT.ts index b71383943e..3738d327d9 100644 --- a/packages/client/lib/commands/SORT.ts +++ b/packages/client/lib/commands/SORT.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; export interface SortOptions { @@ -11,19 +12,19 @@ export interface SortOptions { ALPHA?: boolean; } -export function transformSortArguments( - command: RedisArgument, +export function parseSortArguments( + parser: CommandParser, key: RedisArgument, options?: SortOptions ) { - const args: Array = [command, key]; + parser.pushKey(key); if (options?.BY) { - args.push('BY', options.BY); + parser.push('BY', options.BY); } if (options?.LIMIT) { - args.push( + parser.push( 'LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString() @@ -33,27 +34,27 @@ export function transformSortArguments( if (options?.GET) { if (Array.isArray(options.GET)) { for (const pattern of options.GET) { - args.push('GET', pattern); + parser.push('GET', pattern); } } else { - args.push('GET', options.GET); + parser.push('GET', options.GET); } } if (options?.DIRECTION) { - args.push(options.DIRECTION); + parser.push(options.DIRECTION); } if (options?.ALPHA) { - args.push('ALPHA'); + parser.push('ALPHA'); } - - return args; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: transformSortArguments.bind(undefined, 'SORT'), + parseCommand(parser: CommandParser, key: RedisArgument, options?: SortOptions) { + parser.push('SORT'); + parseSortArguments(parser, key, options); + }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SORT_RO.spec.ts b/packages/client/lib/commands/SORT_RO.spec.ts index 963416ae63..86f8e50703 100644 --- a/packages/client/lib/commands/SORT_RO.spec.ts +++ b/packages/client/lib/commands/SORT_RO.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SORT_RO from './SORT_RO'; +import { parseArgs } from './generic-transformers'; describe('SORT_RO', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('SORT_RO', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SORT_RO.transformArguments('key'), + parseArgs(SORT_RO, 'key'), ['SORT_RO', 'key'] ); }); it('with BY', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { BY: 'pattern' }), ['SORT_RO', 'key', 'BY', 'pattern'] @@ -24,7 +25,7 @@ describe('SORT_RO', () => { it('with LIMIT', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { LIMIT: { offset: 0, count: 1 @@ -37,7 +38,7 @@ describe('SORT_RO', () => { describe('with GET', () => { it('string', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { GET: 'pattern' }), ['SORT_RO', 'key', 'GET', 'pattern'] @@ -46,7 +47,7 @@ describe('SORT_RO', () => { it('array', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { GET: ['1', '2'] }), ['SORT_RO', 'key', 'GET', '1', 'GET', '2'] @@ -56,7 +57,7 @@ describe('SORT_RO', () => { it('with DIRECTION', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { DIRECTION: 'ASC' }), ['SORT_RO', 'key', 'ASC'] @@ -65,7 +66,7 @@ describe('SORT_RO', () => { it('with ALPHA', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { ALPHA: true }), ['SORT_RO', 'key', 'ALPHA'] @@ -74,7 +75,7 @@ describe('SORT_RO', () => { it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => { assert.deepEqual( - SORT_RO.transformArguments('key', { + parseArgs(SORT_RO, 'key', { BY: 'pattern', LIMIT: { offset: 0, diff --git a/packages/client/lib/commands/SORT_RO.ts b/packages/client/lib/commands/SORT_RO.ts index 459a0bbc03..9901907c22 100644 --- a/packages/client/lib/commands/SORT_RO.ts +++ b/packages/client/lib/commands/SORT_RO.ts @@ -1,9 +1,13 @@ import { Command } from '../RESP/types'; -import SORT, { transformSortArguments } from './SORT'; +import SORT, { parseSortArguments } from './SORT'; export default { - FIRST_KEY_INDEX: SORT.FIRST_KEY_INDEX, IS_READ_ONLY: true, - transformArguments: transformSortArguments.bind(undefined, 'SORT_RO'), + parseCommand(...args: Parameters) { + const parser = args[0]; + + parser.push('SORT_RO'); + parseSortArguments(...args); + }, transformReply: SORT.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SORT_STORE.spec.ts b/packages/client/lib/commands/SORT_STORE.spec.ts index 49efd4c6ad..a812cec52c 100644 --- a/packages/client/lib/commands/SORT_STORE.spec.ts +++ b/packages/client/lib/commands/SORT_STORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SORT_STORE from './SORT_STORE'; +import { parseArgs } from './generic-transformers'; describe('SORT STORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination'), + parseArgs(SORT_STORE, 'source', 'destination'), ['SORT', 'source', 'STORE', 'destination'] ); }); it('with BY', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { BY: 'pattern' }), ['SORT', 'source', 'BY', 'pattern', 'STORE', 'destination'] @@ -22,7 +23,7 @@ describe('SORT STORE', () => { it('with LIMIT', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { LIMIT: { offset: 0, count: 1 @@ -35,7 +36,7 @@ describe('SORT STORE', () => { describe('with GET', () => { it('string', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { GET: 'pattern' }), ['SORT', 'source', 'GET', 'pattern', 'STORE', 'destination'] @@ -44,7 +45,7 @@ describe('SORT STORE', () => { it('array', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { GET: ['1', '2'] }), ['SORT', 'source', 'GET', '1', 'GET', '2', 'STORE', 'destination'] @@ -54,7 +55,7 @@ describe('SORT STORE', () => { it('with DIRECTION', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { DIRECTION: 'ASC' }), ['SORT', 'source', 'ASC', 'STORE', 'destination'] @@ -63,7 +64,7 @@ describe('SORT STORE', () => { it('with ALPHA', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { ALPHA: true }), ['SORT', 'source', 'ALPHA', 'STORE', 'destination'] @@ -72,7 +73,7 @@ describe('SORT STORE', () => { it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => { assert.deepEqual( - SORT_STORE.transformArguments('source', 'destination', { + parseArgs(SORT_STORE, 'source', 'destination', { BY: 'pattern', LIMIT: { offset: 0, diff --git a/packages/client/lib/commands/SORT_STORE.ts b/packages/client/lib/commands/SORT_STORE.ts index b6ad709fb6..15c94732e4 100644 --- a/packages/client/lib/commands/SORT_STORE.ts +++ b/packages/client/lib/commands/SORT_STORE.ts @@ -1,17 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import SORT, { SortOptions } from './SORT'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - source: RedisArgument, - destination: RedisArgument, - options?: SortOptions - ) { - const args = SORT.transformArguments(source, options); - args.push('STORE', destination); - return args; + parseCommand(parser: CommandParser, source: RedisArgument, destination: RedisArgument, options?: SortOptions) { + SORT.parseCommand(parser, source, options); + parser.push('STORE', destination); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SPOP.spec.ts b/packages/client/lib/commands/SPOP.spec.ts index 896c1c820a..f435134416 100644 --- a/packages/client/lib/commands/SPOP.spec.ts +++ b/packages/client/lib/commands/SPOP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SPOP from './SPOP'; +import { parseArgs } from './generic-transformers'; describe('SPOP', () => { it('transformArguments', () => { assert.deepEqual( - SPOP.transformArguments('key'), + parseArgs(SPOP, 'key'), ['SPOP', 'key'] ); }); diff --git a/packages/client/lib/commands/SPOP.ts b/packages/client/lib/commands/SPOP.ts index 4b061a8630..38f40989e6 100644 --- a/packages/client/lib/commands/SPOP.ts +++ b/packages/client/lib/commands/SPOP.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument) { - return ['SPOP', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('SPOP'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SPOP_COUNT.spec.ts b/packages/client/lib/commands/SPOP_COUNT.spec.ts index ddad816b42..935ff43780 100644 --- a/packages/client/lib/commands/SPOP_COUNT.spec.ts +++ b/packages/client/lib/commands/SPOP_COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SPOP_COUNT from './SPOP_COUNT'; +import { parseArgs } from './generic-transformers'; describe('SPOP_COUNT', () => { it('transformArguments', () => { assert.deepEqual( - SPOP_COUNT.transformArguments('key', 1), + parseArgs(SPOP_COUNT, 'key', 1), ['SPOP', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/SPOP_COUNT.ts b/packages/client/lib/commands/SPOP_COUNT.ts index 4c68ae8d08..0536203be9 100644 --- a/packages/client/lib/commands/SPOP_COUNT.ts +++ b/packages/client/lib/commands/SPOP_COUNT.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, count: number) { - return ['SPOP', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('SPOP'); + parser.pushKey(key); + parser.push(count.toString()); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SPUBLISH.spec.ts b/packages/client/lib/commands/SPUBLISH.spec.ts index 741372d015..5a53bc40b7 100644 --- a/packages/client/lib/commands/SPUBLISH.spec.ts +++ b/packages/client/lib/commands/SPUBLISH.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SPUBLISH from './SPUBLISH'; +import { parseArgs } from './generic-transformers'; describe('SPUBLISH', () => { testUtils.isVersionGreaterThanHook([7]); it('transformArguments', () => { assert.deepEqual( - SPUBLISH.transformArguments('channel', 'message'), + parseArgs(SPUBLISH, 'channel', 'message'), ['SPUBLISH', 'channel', 'message'] ); }); diff --git a/packages/client/lib/commands/SPUBLISH.ts b/packages/client/lib/commands/SPUBLISH.ts index 19d84b03c6..77d93e617d 100644 --- a/packages/client/lib/commands/SPUBLISH.ts +++ b/packages/client/lib/commands/SPUBLISH.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(channel: RedisArgument, message: RedisArgument) { - return ['SPUBLISH', channel, message]; + parseCommand(parser: CommandParser, channel: RedisArgument, message: RedisArgument) { + parser.push('SPUBLISH'); + parser.pushKey(channel); + parser.push(message); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SRANDMEMBER.spec.ts b/packages/client/lib/commands/SRANDMEMBER.spec.ts index a7df01f0eb..637aac27b2 100644 --- a/packages/client/lib/commands/SRANDMEMBER.spec.ts +++ b/packages/client/lib/commands/SRANDMEMBER.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SRANDMEMBER from './SRANDMEMBER'; +import { parseArgs } from './generic-transformers'; describe('SRANDMEMBER', () => { it('transformArguments', () => { assert.deepEqual( - SRANDMEMBER.transformArguments('key'), + parseArgs(SRANDMEMBER, 'key'), ['SRANDMEMBER', 'key'] ); }); diff --git a/packages/client/lib/commands/SRANDMEMBER.ts b/packages/client/lib/commands/SRANDMEMBER.ts index 6a2373ae92..4285f7aa17 100644 --- a/packages/client/lib/commands/SRANDMEMBER.ts +++ b/packages/client/lib/commands/SRANDMEMBER.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['SRANDMEMBER', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('SRANDMEMBER') + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts b/packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts index 364eb64034..13bb0d52d9 100644 --- a/packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts +++ b/packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SRANDMEMBER_COUNT from './SRANDMEMBER_COUNT'; +import { parseArgs } from './generic-transformers'; describe('SRANDMEMBER COUNT', () => { it('transformArguments', () => { assert.deepEqual( - SRANDMEMBER_COUNT.transformArguments('key', 1), + parseArgs(SRANDMEMBER_COUNT, 'key', 1), ['SRANDMEMBER', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/SRANDMEMBER_COUNT.ts b/packages/client/lib/commands/SRANDMEMBER_COUNT.ts index 778f3d8f62..dd72245c3b 100644 --- a/packages/client/lib/commands/SRANDMEMBER_COUNT.ts +++ b/packages/client/lib/commands/SRANDMEMBER_COUNT.ts @@ -1,13 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import SRANDMEMBER from './SRANDMEMBER'; export default { - FIRST_KEY_INDEX: SRANDMEMBER.FIRST_KEY_INDEX, IS_READ_ONLY: SRANDMEMBER.IS_READ_ONLY, - transformArguments(key: RedisArgument, count: number) { - const args = SRANDMEMBER.transformArguments(key); - args.push(count.toString()); - return args; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + SRANDMEMBER.parseCommand(parser, key); + parser.push(count.toString()); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SREM.spec.ts b/packages/client/lib/commands/SREM.spec.ts index f17c6fb118..6def4178fc 100644 --- a/packages/client/lib/commands/SREM.spec.ts +++ b/packages/client/lib/commands/SREM.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SREM from './SREM'; +import { parseArgs } from './generic-transformers'; describe('SREM', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SREM.transformArguments('key', 'member'), + parseArgs(SREM, 'key', 'member'), ['SREM', 'key', 'member'] ); }); it('array', () => { assert.deepEqual( - SREM.transformArguments('key', ['1', '2']), + parseArgs(SREM, 'key', ['1', '2']), ['SREM', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SREM.ts b/packages/client/lib/commands/SREM.ts index daa95493d0..75053474cc 100644 --- a/packages/client/lib/commands/SREM.ts +++ b/packages/client/lib/commands/SREM.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, members: RedisVariadicArgument) { - return pushVariadicArguments(['SREM', key], members); + parseCommand(parser: CommandParser, key: RedisArgument, members: RedisVariadicArgument) { + parser.push('SREM'); + parser.pushKey(key); + parser.pushVariadic(members); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SSCAN.spec.ts b/packages/client/lib/commands/SSCAN.spec.ts index 29a13306fd..e5d689c6e9 100644 --- a/packages/client/lib/commands/SSCAN.spec.ts +++ b/packages/client/lib/commands/SSCAN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SSCAN from './SSCAN'; +import { parseArgs } from './generic-transformers'; describe('SSCAN', () => { describe('transformArguments', () => { it('cusror only', () => { assert.deepEqual( - SSCAN.transformArguments('key', '0'), + parseArgs(SSCAN, 'key', '0'), ['SSCAN', 'key', '0'] ); }); it('with MATCH', () => { assert.deepEqual( - SSCAN.transformArguments('key', '0', { + parseArgs(SSCAN, 'key', '0', { MATCH: 'pattern' }), ['SSCAN', 'key', '0', 'MATCH', 'pattern'] @@ -22,7 +23,7 @@ describe('SSCAN', () => { it('with COUNT', () => { assert.deepEqual( - SSCAN.transformArguments('key', '0', { + parseArgs(SSCAN, 'key', '0', { COUNT: 1 }), ['SSCAN', 'key', '0', 'COUNT', '1'] @@ -31,7 +32,7 @@ describe('SSCAN', () => { it('with MATCH & COUNT', () => { assert.deepEqual( - SSCAN.transformArguments('key', '0', { + parseArgs(SSCAN, 'key', '0', { MATCH: 'pattern', COUNT: 1 }), diff --git a/packages/client/lib/commands/SSCAN.ts b/packages/client/lib/commands/SSCAN.ts index f47144d834..22634d5624 100644 --- a/packages/client/lib/commands/SSCAN.ts +++ b/packages/client/lib/commands/SSCAN.ts @@ -1,15 +1,18 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; -import { ScanCommonOptions, pushScanArguments } from './SCAN'; +import { ScanCommonOptions, parseScanArguments} from './SCAN'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, cursor: RedisArgument, options?: ScanCommonOptions ) { - return pushScanArguments(['SSCAN', key], cursor, options); + parser.push('SSCAN'); + parser.pushKey(key); + parseScanArguments(parser, cursor, options); }, transformReply([cursor, members]: [BlobStringReply, Array]) { return { diff --git a/packages/client/lib/commands/STRLEN.spec.ts b/packages/client/lib/commands/STRLEN.spec.ts index b07c07b909..dbb7a08541 100644 --- a/packages/client/lib/commands/STRLEN.spec.ts +++ b/packages/client/lib/commands/STRLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import STRLEN from './STRLEN'; +import { parseArgs } from './generic-transformers'; describe('STRLEN', () => { it('transformArguments', () => { assert.deepEqual( - STRLEN.transformArguments('key'), + parseArgs(STRLEN, 'key'), ['STRLEN', 'key'] ); }); diff --git a/packages/client/lib/commands/STRLEN.ts b/packages/client/lib/commands/STRLEN.ts index 594530ff6b..34e0430fc9 100644 --- a/packages/client/lib/commands/STRLEN.ts +++ b/packages/client/lib/commands/STRLEN.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['STRLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('STRLEN'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SUNION.spec.ts b/packages/client/lib/commands/SUNION.spec.ts index ff00c44a1b..a4389d4236 100644 --- a/packages/client/lib/commands/SUNION.spec.ts +++ b/packages/client/lib/commands/SUNION.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUNION from './SUNION'; +import { parseArgs } from './generic-transformers'; describe('SUNION', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SUNION.transformArguments('key'), + parseArgs(SUNION, 'key'), ['SUNION', 'key'] ); }); it('array', () => { assert.deepEqual( - SUNION.transformArguments(['1', '2']), + parseArgs(SUNION, ['1', '2']), ['SUNION', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SUNION.ts b/packages/client/lib/commands/SUNION.ts index 42042217e2..3d9a5954a7 100644 --- a/packages/client/lib/commands/SUNION.ts +++ b/packages/client/lib/commands/SUNION.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArguments(['SUNION'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('SUNION'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SUNIONSTORE.spec.ts b/packages/client/lib/commands/SUNIONSTORE.spec.ts index 790fd78060..8f3db2cacd 100644 --- a/packages/client/lib/commands/SUNIONSTORE.spec.ts +++ b/packages/client/lib/commands/SUNIONSTORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUNIONSTORE from './SUNIONSTORE'; +import { parseArgs } from './generic-transformers'; describe('SUNIONSTORE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - SUNIONSTORE.transformArguments('destination', 'key'), + parseArgs(SUNIONSTORE, 'destination', 'key'), ['SUNIONSTORE', 'destination', 'key'] ); }); it('array', () => { assert.deepEqual( - SUNIONSTORE.transformArguments('destination', ['1', '2']), + parseArgs(SUNIONSTORE, 'destination', ['1', '2']), ['SUNIONSTORE', 'destination', '1', '2'] ); }); diff --git a/packages/client/lib/commands/SUNIONSTORE.ts b/packages/client/lib/commands/SUNIONSTORE.ts index 9adaa9288f..e2f43ecb1c 100644 --- a/packages/client/lib/commands/SUNIONSTORE.ts +++ b/packages/client/lib/commands/SUNIONSTORE.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - destination: RedisArgument, - keys: RedisVariadicArgument - ) { - return pushVariadicArguments(['SUNIONSTORE', destination], keys); + parseCommand(parser: CommandParser, destination: RedisArgument, keys: RedisVariadicArgument) { + parser.push('SUNIONSTORE'); + parser.pushKey(destination); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/SWAPDB.spec.ts b/packages/client/lib/commands/SWAPDB.spec.ts index 9331854c13..a3b53b2721 100644 --- a/packages/client/lib/commands/SWAPDB.spec.ts +++ b/packages/client/lib/commands/SWAPDB.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SWAPDB from './SWAPDB'; +import { parseArgs } from './generic-transformers'; describe('SWAPDB', () => { it('transformArguments', () => { assert.deepEqual( - SWAPDB.transformArguments(0, 1), + parseArgs(SWAPDB, 0, 1), ['SWAPDB', '0', '1'] ); }); diff --git a/packages/client/lib/commands/SWAPDB.ts b/packages/client/lib/commands/SWAPDB.ts index f3b768e95f..e59c75715c 100644 --- a/packages/client/lib/commands/SWAPDB.ts +++ b/packages/client/lib/commands/SWAPDB.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(index1: number, index2: number) { - return ['SWAPDB', index1.toString(), index2.toString()]; + parseCommand(parser: CommandParser, index1: number, index2: number) { + parser.push('SWAPDB', index1.toString(), index2.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/TIME.spec.ts b/packages/client/lib/commands/TIME.spec.ts index d9dd9667ea..4ee704f0dd 100644 --- a/packages/client/lib/commands/TIME.spec.ts +++ b/packages/client/lib/commands/TIME.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TIME from './TIME'; +import { parseArgs } from './generic-transformers'; describe('TIME', () => { it('transformArguments', () => { assert.deepEqual( - TIME.transformArguments(), + parseArgs(TIME), ['TIME'] ); }); diff --git a/packages/client/lib/commands/TIME.ts b/packages/client/lib/commands/TIME.ts index d4dc67ae48..b25af710e1 100644 --- a/packages/client/lib/commands/TIME.ts +++ b/packages/client/lib/commands/TIME.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { BlobStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['TIME']; + parseCommand(parser: CommandParser) { + parser.push('TIME'); }, transformReply: undefined as unknown as () => [ unixTimestamp: BlobStringReply<`${number}`>, diff --git a/packages/client/lib/commands/TOUCH.spec.ts b/packages/client/lib/commands/TOUCH.spec.ts index 48e77900ee..69a3498346 100644 --- a/packages/client/lib/commands/TOUCH.spec.ts +++ b/packages/client/lib/commands/TOUCH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TOUCH from './TOUCH'; +import { parseArgs } from './generic-transformers'; describe('TOUCH', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - TOUCH.transformArguments('key'), + parseArgs(TOUCH, 'key'), ['TOUCH', 'key'] ); }); it('array', () => { assert.deepEqual( - TOUCH.transformArguments(['1', '2']), + parseArgs(TOUCH, ['1', '2']), ['TOUCH', '1', '2'] ); }); diff --git a/packages/client/lib/commands/TOUCH.ts b/packages/client/lib/commands/TOUCH.ts index c1c19402f8..c765c9f834 100644 --- a/packages/client/lib/commands/TOUCH.ts +++ b/packages/client/lib/commands/TOUCH.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisVariadicArgument) { - return pushVariadicArguments(['TOUCH'], key); + parseCommand(parser: CommandParser, key: RedisVariadicArgument) { + parser.push('TOUCH'); + parser.pushKeys(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/TTL.spec.ts b/packages/client/lib/commands/TTL.spec.ts index 6b709226a2..4d36053c02 100644 --- a/packages/client/lib/commands/TTL.spec.ts +++ b/packages/client/lib/commands/TTL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TTL from './TTL'; +import { parseArgs } from './generic-transformers'; describe('TTL', () => { it('transformArguments', () => { assert.deepEqual( - TTL.transformArguments('key'), + parseArgs(TTL, 'key'), ['TTL', 'key'] ); }); diff --git a/packages/client/lib/commands/TTL.ts b/packages/client/lib/commands/TTL.ts index 65c3b7b026..8420089fcb 100644 --- a/packages/client/lib/commands/TTL.ts +++ b/packages/client/lib/commands/TTL.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TTL', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TTL'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/TYPE.spec.ts b/packages/client/lib/commands/TYPE.spec.ts index 45cf1cfc1c..ae7392cdce 100644 --- a/packages/client/lib/commands/TYPE.spec.ts +++ b/packages/client/lib/commands/TYPE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TYPE from './TYPE'; +import { parseArgs } from './generic-transformers'; describe('TYPE', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - TYPE.transformArguments('key'), + parseArgs(TYPE, 'key'), ['TYPE', 'key'] ); }); diff --git a/packages/client/lib/commands/TYPE.ts b/packages/client/lib/commands/TYPE.ts index 09f6887492..ffc592994d 100644 --- a/packages/client/lib/commands/TYPE.ts +++ b/packages/client/lib/commands/TYPE.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['TYPE', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('TYPE'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/UNLINK.spec.ts b/packages/client/lib/commands/UNLINK.spec.ts index 1e37478300..2c32bee8e3 100644 --- a/packages/client/lib/commands/UNLINK.spec.ts +++ b/packages/client/lib/commands/UNLINK.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import UNLINK from './UNLINK'; +import { parseArgs } from './generic-transformers'; describe('UNLINK', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - UNLINK.transformArguments('key'), + parseArgs(UNLINK, 'key'), ['UNLINK', 'key'] ); }); it('array', () => { assert.deepEqual( - UNLINK.transformArguments(['1', '2']), + parseArgs(UNLINK, ['1', '2']), ['UNLINK', '1', '2'] ); }); diff --git a/packages/client/lib/commands/UNLINK.ts b/packages/client/lib/commands/UNLINK.ts index 2346573f39..14d1e70027 100644 --- a/packages/client/lib/commands/UNLINK.ts +++ b/packages/client/lib/commands/UNLINK.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisVariadicArgument) { - return pushVariadicArguments(['UNLINK'], key); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('UNLINK'); + parser.pushKeys(keys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/WAIT.spec.ts b/packages/client/lib/commands/WAIT.spec.ts index 61b197c90b..d2778e7967 100644 --- a/packages/client/lib/commands/WAIT.spec.ts +++ b/packages/client/lib/commands/WAIT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import WAIT from './WAIT'; +import { parseArgs } from './generic-transformers'; describe('WAIT', () => { it('transformArguments', () => { assert.deepEqual( - WAIT.transformArguments(0, 1), + parseArgs(WAIT, 0, 1), ['WAIT', '0', '1'] ); }); diff --git a/packages/client/lib/commands/WAIT.ts b/packages/client/lib/commands/WAIT.ts index 21c39a643e..df45a12373 100644 --- a/packages/client/lib/commands/WAIT.ts +++ b/packages/client/lib/commands/WAIT.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(numberOfReplicas: number, timeout: number) { - return ['WAIT', numberOfReplicas.toString(), timeout.toString()]; + parseCommand(parser: CommandParser, numberOfReplicas: number, timeout: number) { + parser.push('WAIT', numberOfReplicas.toString(), timeout.toString()); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XACK.spec.ts b/packages/client/lib/commands/XACK.spec.ts index 81a7954ffd..4ad60b256d 100644 --- a/packages/client/lib/commands/XACK.spec.ts +++ b/packages/client/lib/commands/XACK.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XACK from './XACK'; +import { parseArgs } from './generic-transformers'; describe('XACK', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - XACK.transformArguments('key', 'group', '0-0'), + parseArgs(XACK, 'key', 'group', '0-0'), ['XACK', 'key', 'group', '0-0'] ); }); it('array', () => { assert.deepEqual( - XACK.transformArguments('key', 'group', ['0-0', '1-0']), + parseArgs(XACK, 'key', 'group', ['0-0', '1-0']), ['XACK', 'key', 'group', '0-0', '1-0'] ); }); diff --git a/packages/client/lib/commands/XACK.ts b/packages/client/lib/commands/XACK.ts index 89b2d58120..2500134f1c 100644 --- a/packages/client/lib/commands/XACK.ts +++ b/packages/client/lib/commands/XACK.ts @@ -1,15 +1,15 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - key: RedisArgument, - group: RedisArgument, - id: RedisVariadicArgument - ) { - return pushVariadicArguments(['XACK', key, group], id); + parseCommand(parser: CommandParser, key: RedisArgument, group: RedisArgument, id: RedisVariadicArgument) { + parser.push('XACK'); + parser.pushKey(key); + parser.push(group) + parser.pushVariadic(id); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; + \ No newline at end of file diff --git a/packages/client/lib/commands/XADD.spec.ts b/packages/client/lib/commands/XADD.spec.ts index 10c6f4daa5..321581d086 100644 --- a/packages/client/lib/commands/XADD.spec.ts +++ b/packages/client/lib/commands/XADD.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XADD from './XADD'; +import { parseArgs } from './generic-transformers'; describe('XADD', () => { describe('transformArguments', () => { it('single field', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { field: 'value' }), ['XADD', 'key', '*', 'field', 'value'] @@ -15,7 +16,7 @@ describe('XADD', () => { it('multiple fields', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { '1': 'I', '2': 'II' }), @@ -25,7 +26,7 @@ describe('XADD', () => { it('with TRIM', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { field: 'value' }, { TRIM: { @@ -38,7 +39,7 @@ describe('XADD', () => { it('with TRIM.strategy', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { field: 'value' }, { TRIM: { @@ -52,7 +53,7 @@ describe('XADD', () => { it('with TRIM.strategyModifier', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { field: 'value' }, { TRIM: { @@ -66,7 +67,7 @@ describe('XADD', () => { it('with TRIM.limit', () => { assert.deepEqual( - XADD.transformArguments('key', '*', { + parseArgs(XADD, 'key', '*', { field: 'value' }, { TRIM: { diff --git a/packages/client/lib/commands/XADD.ts b/packages/client/lib/commands/XADD.ts index b681069c72..cb9d0f5fad 100644 --- a/packages/client/lib/commands/XADD.ts +++ b/packages/client/lib/commands/XADD.ts @@ -1,4 +1,6 @@ -import { RedisArgument, BlobStringReply, Command, CommandArguments } from '../RESP/types'; +import { CommandParser } from '../client/parser'; +import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; +import { Tail } from './generic-transformers'; export interface XAddOptions { TRIM?: { @@ -9,47 +11,47 @@ export interface XAddOptions { }; } -export function pushXAddArguments( - args: CommandArguments, +export function parseXAddArguments( + optional: RedisArgument | undefined, + parser: CommandParser, + key: RedisArgument, id: RedisArgument, message: Record, options?: XAddOptions ) { + parser.push('XADD'); + parser.pushKey(key); + if (optional) { + parser.push(optional); + } + if (options?.TRIM) { if (options.TRIM.strategy) { - args.push(options.TRIM.strategy); + parser.push(options.TRIM.strategy); } if (options.TRIM.strategyModifier) { - args.push(options.TRIM.strategyModifier); + parser.push(options.TRIM.strategyModifier); } - args.push(options.TRIM.threshold.toString()); + parser.push(options.TRIM.threshold.toString()); if (options.TRIM.limit) { - args.push('LIMIT', options.TRIM.limit.toString()); + parser.push('LIMIT', options.TRIM.limit.toString()); } } - args.push(id); + parser.push(id); for (const [key, value] of Object.entries(message)) { - args.push(key, value); + parser.push(key, value); } - - return args; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - key: RedisArgument, - id: RedisArgument, - message: Record, - options?: XAddOptions - ) { - return pushXAddArguments(['XADD', key], id, message, options); + parseCommand(...args: Tail>) { + return parseXAddArguments(undefined, ...args); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XADD_NOMKSTREAM.spec.ts b/packages/client/lib/commands/XADD_NOMKSTREAM.spec.ts index a3dd5602a3..97927f212f 100644 --- a/packages/client/lib/commands/XADD_NOMKSTREAM.spec.ts +++ b/packages/client/lib/commands/XADD_NOMKSTREAM.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XADD_NOMKSTREAM from './XADD_NOMKSTREAM'; +import { parseArgs } from './generic-transformers'; describe('XADD NOMKSTREAM', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,7 +9,7 @@ describe('XADD NOMKSTREAM', () => { describe('transformArguments', () => { it('single field', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { field: 'value' }), ['XADD', 'key', 'NOMKSTREAM', '*', 'field', 'value'] @@ -17,7 +18,7 @@ describe('XADD NOMKSTREAM', () => { it('multiple fields', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { '1': 'I', '2': 'II' }), @@ -27,7 +28,7 @@ describe('XADD NOMKSTREAM', () => { it('with TRIM', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { field: 'value' }, { TRIM: { @@ -40,7 +41,7 @@ describe('XADD NOMKSTREAM', () => { it('with TRIM.strategy', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { field: 'value' }, { TRIM: { @@ -54,7 +55,7 @@ describe('XADD NOMKSTREAM', () => { it('with TRIM.strategyModifier', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { field: 'value' }, { TRIM: { @@ -68,7 +69,7 @@ describe('XADD NOMKSTREAM', () => { it('with TRIM.limit', () => { assert.deepEqual( - XADD_NOMKSTREAM.transformArguments('key', '*', { + parseArgs(XADD_NOMKSTREAM, 'key', '*', { field: 'value' }, { TRIM: { diff --git a/packages/client/lib/commands/XADD_NOMKSTREAM.ts b/packages/client/lib/commands/XADD_NOMKSTREAM.ts index 65e7dd566e..9d33374be4 100644 --- a/packages/client/lib/commands/XADD_NOMKSTREAM.ts +++ b/packages/client/lib/commands/XADD_NOMKSTREAM.ts @@ -1,16 +1,11 @@ -import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; -import { XAddOptions, pushXAddArguments } from './XADD'; +import { BlobStringReply, NullReply, Command } from '../RESP/types'; +import { Tail } from './generic-transformers'; +import { parseXAddArguments } from './XADD'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( - key: RedisArgument, - id: RedisArgument, - message: Record, - options?: XAddOptions - ) { - return pushXAddArguments(['XADD', key, 'NOMKSTREAM'], id, message, options); + parseCommand(...args: Tail>) { + return parseXAddArguments('NOMKSTREAM', ...args); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XAUTOCLAIM.spec.ts b/packages/client/lib/commands/XAUTOCLAIM.spec.ts index 256c58cc4d..58b09a63e7 100644 --- a/packages/client/lib/commands/XAUTOCLAIM.spec.ts +++ b/packages/client/lib/commands/XAUTOCLAIM.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XAUTOCLAIM from './XAUTOCLAIM'; +import { parseArgs } from './generic-transformers'; describe('XAUTOCLAIM', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('XAUTOCLAIM', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XAUTOCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0'), + parseArgs(XAUTOCLAIM, 'key', 'group', 'consumer', 1, '0-0'), ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0'] ); }); it('with COUNT', () => { assert.deepEqual( - XAUTOCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XAUTOCLAIM, 'key', 'group', 'consumer', 1, '0-0', { COUNT: 1 }), ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'COUNT', '1'] diff --git a/packages/client/lib/commands/XAUTOCLAIM.ts b/packages/client/lib/commands/XAUTOCLAIM.ts index 7d33142de3..19b4f63a2d 100644 --- a/packages/client/lib/commands/XAUTOCLAIM.ts +++ b/packages/client/lib/commands/XAUTOCLAIM.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, TuplesReply, BlobStringReply, ArrayReply, NullReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; import { StreamMessageRawReply, transformStreamMessageNullReply } from './generic-transformers'; @@ -12,9 +13,9 @@ export type XAutoClaimRawReply = TuplesReply<[ ]>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, consumer: RedisArgument, @@ -22,20 +23,13 @@ export default { start: RedisArgument, options?: XAutoClaimOptions ) { - const args = [ - 'XAUTOCLAIM', - key, - group, - consumer, - minIdleTime.toString(), - start - ]; + parser.push('XAUTOCLAIM'); + parser.pushKey(key); + parser.push(group, consumer, minIdleTime.toString(), start); if (options?.COUNT) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } - - return args; }, transformReply(reply: UnwrapReply, preserve?: any, typeMapping?: TypeMapping) { return { diff --git a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts index 96ceb1d811..7891165708 100644 --- a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts +++ b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XAUTOCLAIM_JUSTID from './XAUTOCLAIM_JUSTID'; +import { parseArgs } from './generic-transformers'; describe('XAUTOCLAIM JUSTID', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - XAUTOCLAIM_JUSTID.transformArguments('key', 'group', 'consumer', 1, '0-0'), + parseArgs(XAUTOCLAIM_JUSTID, 'key', 'group', 'consumer', 1, '0-0'), ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'JUSTID'] ); }); diff --git a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts index e2832f2353..c0ebe83748 100644 --- a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts +++ b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts @@ -8,12 +8,11 @@ type XAutoClaimJustIdRawReply = TuplesReply<[ ]>; export default { - FIRST_KEY_INDEX: XAUTOCLAIM.FIRST_KEY_INDEX, IS_READ_ONLY: XAUTOCLAIM.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = XAUTOCLAIM.transformArguments(...args); - redisArgs.push('JUSTID'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + XAUTOCLAIM.parseCommand(...args); + parser.push('JUSTID'); }, transformReply(reply: UnwrapReply) { return { diff --git a/packages/client/lib/commands/XCLAIM.spec.ts b/packages/client/lib/commands/XCLAIM.spec.ts index e8fde2e1a1..9076850922 100644 --- a/packages/client/lib/commands/XCLAIM.spec.ts +++ b/packages/client/lib/commands/XCLAIM.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XCLAIM from './XCLAIM'; +import { parseArgs } from './generic-transformers'; describe('XCLAIM', () => { describe('transformArguments', () => { it('single id (string)', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0'), + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0'), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0'] ); }); it('multiple ids (array)', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, ['0-0', '1-0']), + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, ['0-0', '1-0']), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', '1-0'] ); }); it('with IDLE', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { IDLE: 1 }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'IDLE', '1'] @@ -30,7 +31,7 @@ describe('XCLAIM', () => { describe('with TIME', () => { it('number', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { TIME: 1 }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'TIME', '1'] @@ -40,7 +41,7 @@ describe('XCLAIM', () => { it('Date', () => { const d = new Date(); assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { TIME: d }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'TIME', d.getTime().toString()] @@ -50,7 +51,7 @@ describe('XCLAIM', () => { it('with RETRYCOUNT', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { RETRYCOUNT: 1 }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'RETRYCOUNT', '1'] @@ -59,7 +60,7 @@ describe('XCLAIM', () => { it('with FORCE', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { FORCE: true }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'FORCE'] @@ -68,7 +69,7 @@ describe('XCLAIM', () => { it('with LASTID', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { LASTID: '0-0' }), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'LASTID', '0-0'] @@ -77,7 +78,7 @@ describe('XCLAIM', () => { it('with IDLE, TIME, RETRYCOUNT, FORCE, LASTID', () => { assert.deepEqual( - XCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', { + parseArgs(XCLAIM, 'key', 'group', 'consumer', 1, '0-0', { IDLE: 1, TIME: 1, RETRYCOUNT: 1, diff --git a/packages/client/lib/commands/XCLAIM.ts b/packages/client/lib/commands/XCLAIM.ts index eb9c0b325e..598b1b17ba 100644 --- a/packages/client/lib/commands/XCLAIM.ts +++ b/packages/client/lib/commands/XCLAIM.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NullReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments, StreamMessageRawReply, transformStreamMessageNullReply } from './generic-transformers'; +import { RedisVariadicArgument, StreamMessageRawReply, transformStreamMessageNullReply } from './generic-transformers'; export interface XClaimOptions { IDLE?: number; @@ -10,9 +11,9 @@ export interface XClaimOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, consumer: RedisArgument, @@ -20,35 +21,33 @@ export default { id: RedisVariadicArgument, options?: XClaimOptions ) { - const args = pushVariadicArguments( - ['XCLAIM', key, group, consumer, minIdleTime.toString()], - id - ); + parser.push('XCLAIM'); + parser.pushKey(key); + parser.push(group, consumer, minIdleTime.toString()); + parser.pushVariadic(id); if (options?.IDLE !== undefined) { - args.push('IDLE', options.IDLE.toString()); + parser.push('IDLE', options.IDLE.toString()); } if (options?.TIME !== undefined) { - args.push( + parser.push( 'TIME', (options.TIME instanceof Date ? options.TIME.getTime() : options.TIME).toString() ); } if (options?.RETRYCOUNT !== undefined) { - args.push('RETRYCOUNT', options.RETRYCOUNT.toString()); + parser.push('RETRYCOUNT', options.RETRYCOUNT.toString()); } if (options?.FORCE) { - args.push('FORCE'); + parser.push('FORCE'); } if (options?.LASTID !== undefined) { - args.push('LASTID', options.LASTID); + parser.push('LASTID', options.LASTID); } - - return args; }, transformReply( reply: UnwrapReply>, diff --git a/packages/client/lib/commands/XCLAIM_JUSTID.spec.ts b/packages/client/lib/commands/XCLAIM_JUSTID.spec.ts index 6b580ac3c1..d7bf9fdc70 100644 --- a/packages/client/lib/commands/XCLAIM_JUSTID.spec.ts +++ b/packages/client/lib/commands/XCLAIM_JUSTID.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XCLAIM_JUSTID from './XCLAIM_JUSTID'; +import { parseArgs } from './generic-transformers'; describe('XCLAIM JUSTID', () => { it('transformArguments', () => { assert.deepEqual( - XCLAIM_JUSTID.transformArguments('key', 'group', 'consumer', 1, '0-0'), + parseArgs(XCLAIM_JUSTID, 'key', 'group', 'consumer', 1, '0-0'), ['XCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'JUSTID'] ); }); diff --git a/packages/client/lib/commands/XCLAIM_JUSTID.ts b/packages/client/lib/commands/XCLAIM_JUSTID.ts index 6200c9106e..91be5aafbb 100644 --- a/packages/client/lib/commands/XCLAIM_JUSTID.ts +++ b/packages/client/lib/commands/XCLAIM_JUSTID.ts @@ -2,12 +2,11 @@ import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; import XCLAIM from './XCLAIM'; export default { - FIRST_KEY_INDEX: XCLAIM.FIRST_KEY_INDEX, IS_READ_ONLY: XCLAIM.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = XCLAIM.transformArguments(...args); - redisArgs.push('JUSTID'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + XCLAIM.parseCommand(...args); + parser.push('JUSTID'); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XDEL.spec.ts b/packages/client/lib/commands/XDEL.spec.ts index 15875d3b7b..510168bb76 100644 --- a/packages/client/lib/commands/XDEL.spec.ts +++ b/packages/client/lib/commands/XDEL.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XDEL from './XDEL'; +import { parseArgs } from './generic-transformers'; describe('XDEL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - XDEL.transformArguments('key', '0-0'), + parseArgs(XDEL, 'key', '0-0'), ['XDEL', 'key', '0-0'] ); }); it('array', () => { assert.deepEqual( - XDEL.transformArguments('key', ['0-0', '1-0']), + parseArgs(XDEL, 'key', ['0-0', '1-0']), ['XDEL', 'key', '0-0', '1-0'] ); }); diff --git a/packages/client/lib/commands/XDEL.ts b/packages/client/lib/commands/XDEL.ts index acc9198c2b..ee385203ce 100644 --- a/packages/client/lib/commands/XDEL.ts +++ b/packages/client/lib/commands/XDEL.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, id: RedisVariadicArgument) { - return pushVariadicArguments(['XDEL', key], id); + parseCommand(parser: CommandParser, key: RedisArgument, id: RedisVariadicArgument) { + parser.push('XDEL'); + parser.pushKey(key); + parser.pushVariadic(id); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XGROUP_CREATE.spec.ts b/packages/client/lib/commands/XGROUP_CREATE.spec.ts index 5c9071289c..7c9d6298c6 100644 --- a/packages/client/lib/commands/XGROUP_CREATE.spec.ts +++ b/packages/client/lib/commands/XGROUP_CREATE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XGROUP_CREATE from './XGROUP_CREATE'; +import { parseArgs } from './generic-transformers'; describe('XGROUP CREATE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XGROUP_CREATE.transformArguments('key', 'group', '$'), + parseArgs(XGROUP_CREATE, 'key', 'group', '$'), ['XGROUP', 'CREATE', 'key', 'group', '$'] ); }); it('with MKSTREAM', () => { assert.deepEqual( - XGROUP_CREATE.transformArguments('key', 'group', '$', { + parseArgs(XGROUP_CREATE, 'key', 'group', '$', { MKSTREAM: true }), ['XGROUP', 'CREATE', 'key', 'group', '$', 'MKSTREAM'] @@ -22,7 +23,7 @@ describe('XGROUP CREATE', () => { it('with ENTRIESREAD', () => { assert.deepEqual( - XGROUP_CREATE.transformArguments('key', 'group', '$', { + parseArgs(XGROUP_CREATE, 'key', 'group', '$', { ENTRIESREAD: 1 }), ['XGROUP', 'CREATE', 'key', 'group', '$', 'ENTRIESREAD', '1'] diff --git a/packages/client/lib/commands/XGROUP_CREATE.ts b/packages/client/lib/commands/XGROUP_CREATE.ts index a04fcbeb04..e91186efe2 100644 --- a/packages/client/lib/commands/XGROUP_CREATE.ts +++ b/packages/client/lib/commands/XGROUP_CREATE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export interface XGroupCreateOptions { @@ -9,25 +10,25 @@ export interface XGroupCreateOptions { } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, id: RedisArgument, options?: XGroupCreateOptions ) { - const args = ['XGROUP', 'CREATE', key, group, id]; + parser.push('XGROUP', 'CREATE'); + parser.pushKey(key); + parser.push(group, id); if (options?.MKSTREAM) { - args.push('MKSTREAM'); + parser.push('MKSTREAM'); } if (options?.ENTRIESREAD) { - args.push('ENTRIESREAD', options.ENTRIESREAD.toString()); + parser.push('ENTRIESREAD', options.ENTRIESREAD.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts b/packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts index 3c3ecbda0a..eb749073d3 100644 --- a/packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts +++ b/packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XGROUP_CREATECONSUMER from './XGROUP_CREATECONSUMER'; +import { parseArgs } from './generic-transformers'; describe('XGROUP CREATECONSUMER', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - XGROUP_CREATECONSUMER.transformArguments('key', 'group', 'consumer'), + parseArgs(XGROUP_CREATECONSUMER, 'key', 'group', 'consumer'), ['XGROUP', 'CREATECONSUMER', 'key', 'group', 'consumer'] ); }); diff --git a/packages/client/lib/commands/XGROUP_CREATECONSUMER.ts b/packages/client/lib/commands/XGROUP_CREATECONSUMER.ts index 8fd21ca60d..906bc4c683 100644 --- a/packages/client/lib/commands/XGROUP_CREATECONSUMER.ts +++ b/packages/client/lib/commands/XGROUP_CREATECONSUMER.ts @@ -1,14 +1,17 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command, NumberReply } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, consumer: RedisArgument ) { - return ['XGROUP', 'CREATECONSUMER', key, group, consumer]; + parser.push('XGROUP', 'CREATECONSUMER'); + parser.pushKey(key); + parser.push(group, consumer); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts b/packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts index afc524eef8..fabef789d7 100644 --- a/packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts +++ b/packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XGROUP_DELCONSUMER from './XGROUP_DELCONSUMER'; +import { parseArgs } from './generic-transformers'; describe('XGROUP DELCONSUMER', () => { it('transformArguments', () => { assert.deepEqual( - XGROUP_DELCONSUMER.transformArguments('key', 'group', 'consumer'), + parseArgs(XGROUP_DELCONSUMER, 'key', 'group', 'consumer'), ['XGROUP', 'DELCONSUMER', 'key', 'group', 'consumer'] ); }); diff --git a/packages/client/lib/commands/XGROUP_DELCONSUMER.ts b/packages/client/lib/commands/XGROUP_DELCONSUMER.ts index 53007270e0..360d7e06ca 100644 --- a/packages/client/lib/commands/XGROUP_DELCONSUMER.ts +++ b/packages/client/lib/commands/XGROUP_DELCONSUMER.ts @@ -1,14 +1,17 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, consumer: RedisArgument ) { - return ['XGROUP', 'DELCONSUMER', key, group, consumer]; + parser.push('XGROUP', 'DELCONSUMER'); + parser.pushKey(key); + parser.push(group, consumer); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XGROUP_DESTROY.spec.ts b/packages/client/lib/commands/XGROUP_DESTROY.spec.ts index 6ec9083451..8277c66d3f 100644 --- a/packages/client/lib/commands/XGROUP_DESTROY.spec.ts +++ b/packages/client/lib/commands/XGROUP_DESTROY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XGROUP_DESTROY from './XGROUP_DESTROY'; +import { parseArgs } from './generic-transformers'; describe('XGROUP DESTROY', () => { it('transformArguments', () => { assert.deepEqual( - XGROUP_DESTROY.transformArguments('key', 'group'), + parseArgs(XGROUP_DESTROY, 'key', 'group'), ['XGROUP', 'DESTROY', 'key', 'group'] ); }); diff --git a/packages/client/lib/commands/XGROUP_DESTROY.ts b/packages/client/lib/commands/XGROUP_DESTROY.ts index 6c14d9ae2b..9112f1bcd7 100644 --- a/packages/client/lib/commands/XGROUP_DESTROY.ts +++ b/packages/client/lib/commands/XGROUP_DESTROY.ts @@ -1,13 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( - key: RedisArgument, - group: RedisArgument - ) { - return ['XGROUP', 'DESTROY', key, group]; + parseCommand(parser: CommandParser, key: RedisArgument, group: RedisArgument) { + parser.push('XGROUP', 'DESTROY'); + parser.pushKey(key); + parser.push(group); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XGROUP_SETID.spec.ts b/packages/client/lib/commands/XGROUP_SETID.spec.ts index 891a796d14..6ea0dd79c3 100644 --- a/packages/client/lib/commands/XGROUP_SETID.spec.ts +++ b/packages/client/lib/commands/XGROUP_SETID.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XGROUP_SETID from './XGROUP_SETID'; +import { parseArgs } from './generic-transformers'; describe('XGROUP SETID', () => { it('transformArguments', () => { assert.deepEqual( - XGROUP_SETID.transformArguments('key', 'group', '0'), + parseArgs(XGROUP_SETID, 'key', 'group', '0'), ['XGROUP', 'SETID', 'key', 'group', '0'] ); }); diff --git a/packages/client/lib/commands/XGROUP_SETID.ts b/packages/client/lib/commands/XGROUP_SETID.ts index a23b414433..5b0ddcc32a 100644 --- a/packages/client/lib/commands/XGROUP_SETID.ts +++ b/packages/client/lib/commands/XGROUP_SETID.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export interface XGroupSetIdOptions { @@ -6,21 +7,21 @@ export interface XGroupSetIdOptions { } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, id: RedisArgument, options?: XGroupSetIdOptions ) { - const args = ['XGROUP', 'SETID', key, group, id]; + parser.push('XGROUP', 'SETID'); + parser.pushKey(key); + parser.push(group, id); if (options?.ENTRIESREAD) { - args.push('ENTRIESREAD', options.ENTRIESREAD.toString()); + parser.push('ENTRIESREAD', options.ENTRIESREAD.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts b/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts index 86abdbb149..b1f245dbf1 100644 --- a/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts +++ b/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XINFO_CONSUMERS from './XINFO_CONSUMERS'; +import { parseArgs } from './generic-transformers'; describe('XINFO CONSUMERS', () => { it('transformArguments', () => { assert.deepEqual( - XINFO_CONSUMERS.transformArguments('key', 'group'), + parseArgs(XINFO_CONSUMERS, 'key', 'group'), ['XINFO', 'CONSUMERS', 'key', 'group'] ); }); diff --git a/packages/client/lib/commands/XINFO_CONSUMERS.ts b/packages/client/lib/commands/XINFO_CONSUMERS.ts index ca0076d633..310a40d17f 100644 --- a/packages/client/lib/commands/XINFO_CONSUMERS.ts +++ b/packages/client/lib/commands/XINFO_CONSUMERS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; export type XInfoConsumersReply = ArrayReply>; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - group: RedisArgument - ) { - return ['XINFO', 'CONSUMERS', key, group]; + parseCommand(parser: CommandParser, key: RedisArgument, group: RedisArgument) { + parser.push('XINFO', 'CONSUMERS'); + parser.pushKey(key); + parser.push(group); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/XINFO_GROUPS.spec.ts b/packages/client/lib/commands/XINFO_GROUPS.spec.ts index 1bee02a0e6..a1196f4957 100644 --- a/packages/client/lib/commands/XINFO_GROUPS.spec.ts +++ b/packages/client/lib/commands/XINFO_GROUPS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XINFO_GROUPS from './XINFO_GROUPS'; +import { parseArgs } from './generic-transformers'; describe('XINFO GROUPS', () => { it('transformArguments', () => { assert.deepEqual( - XINFO_GROUPS.transformArguments('key'), + parseArgs(XINFO_GROUPS, 'key'), ['XINFO', 'GROUPS', 'key'] ); }); diff --git a/packages/client/lib/commands/XINFO_GROUPS.ts b/packages/client/lib/commands/XINFO_GROUPS.ts index 24661ecde8..e7f8874125 100644 --- a/packages/client/lib/commands/XINFO_GROUPS.ts +++ b/packages/client/lib/commands/XINFO_GROUPS.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, NullReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types'; export type XInfoGroupsReply = ArrayReply>; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['XINFO', 'GROUPS', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('XINFO', 'GROUPS'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/XINFO_STREAM.spec.ts b/packages/client/lib/commands/XINFO_STREAM.spec.ts index 9e6939092e..7e1829f305 100644 --- a/packages/client/lib/commands/XINFO_STREAM.spec.ts +++ b/packages/client/lib/commands/XINFO_STREAM.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XINFO_STREAM from './XINFO_STREAM'; +import { parseArgs } from './generic-transformers'; describe('XINFO STREAM', () => { it('transformArguments', () => { assert.deepEqual( - XINFO_STREAM.transformArguments('key'), + parseArgs(XINFO_STREAM, 'key'), ['XINFO', 'STREAM', 'key'] ); }); diff --git a/packages/client/lib/commands/XINFO_STREAM.ts b/packages/client/lib/commands/XINFO_STREAM.ts index 04721d0ad3..bb102c591b 100644 --- a/packages/client/lib/commands/XINFO_STREAM.ts +++ b/packages/client/lib/commands/XINFO_STREAM.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, TuplesToMapReply, BlobStringReply, NumberReply, NullReply, TuplesReply, ArrayReply, UnwrapReply, Command } from '../RESP/types'; import { isNullReply, transformTuplesReply } from './generic-transformers'; @@ -18,10 +19,10 @@ export type XInfoStreamReply = TuplesToMapReply<[ ]>; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['XINFO', 'STREAM', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('XINFO', 'STREAM'); + parser.pushKey(key); }, transformReply: { // TODO: is there a "type safe" way to do it? diff --git a/packages/client/lib/commands/XLEN.spec.ts b/packages/client/lib/commands/XLEN.spec.ts index 164a6d6f09..3e22b9aebf 100644 --- a/packages/client/lib/commands/XLEN.spec.ts +++ b/packages/client/lib/commands/XLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XLEN from './XLEN'; +import { parseArgs } from './generic-transformers'; describe('XLEN', () => { - it('transformArguments', () => { + it('processCommand', () => { assert.deepEqual( - XLEN.transformArguments('key'), + parseArgs(XLEN, 'key'), ['XLEN', 'key'] ); }); diff --git a/packages/client/lib/commands/XLEN.ts b/packages/client/lib/commands/XLEN.ts index d2ed566a19..39d47187b2 100644 --- a/packages/client/lib/commands/XLEN.ts +++ b/packages/client/lib/commands/XLEN.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['XLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('XLEN'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XPENDING.spec.ts b/packages/client/lib/commands/XPENDING.spec.ts index e6600cce38..55cb957fc6 100644 --- a/packages/client/lib/commands/XPENDING.spec.ts +++ b/packages/client/lib/commands/XPENDING.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XPENDING from './XPENDING'; +import { parseArgs } from './generic-transformers'; describe('XPENDING', () => { describe('transformArguments', () => { it('transformArguments', () => { assert.deepEqual( - XPENDING.transformArguments('key', 'group'), + parseArgs(XPENDING, 'key', 'group'), ['XPENDING', 'key', 'group'] ); }); diff --git a/packages/client/lib/commands/XPENDING.ts b/packages/client/lib/commands/XPENDING.ts index a6ca4f5a77..11c944c61e 100644 --- a/packages/client/lib/commands/XPENDING.ts +++ b/packages/client/lib/commands/XPENDING.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, ArrayReply, TuplesReply, NumberReply, UnwrapReply, Command } from '../RESP/types'; type XPendingRawReply = TuplesReply<[ @@ -11,10 +12,12 @@ type XPendingRawReply = TuplesReply<[ ]>; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, group: RedisArgument) { - return ['XPENDING', key, group]; + parseCommand(parser: CommandParser, key: RedisArgument, group: RedisArgument) { + parser.push('XPENDING'); + parser.pushKey(key); + parser.push(group); }, transformReply(reply: UnwrapReply) { const consumers = reply[3] as unknown as UnwrapReply; diff --git a/packages/client/lib/commands/XPENDING_RANGE.spec.ts b/packages/client/lib/commands/XPENDING_RANGE.spec.ts index a66484fd2e..33cd836f2a 100644 --- a/packages/client/lib/commands/XPENDING_RANGE.spec.ts +++ b/packages/client/lib/commands/XPENDING_RANGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XPENDING_RANGE from './XPENDING_RANGE'; +import { parseArgs } from './generic-transformers'; describe('XPENDING RANGE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XPENDING_RANGE.transformArguments('key', 'group', '-', '+', 1), + parseArgs(XPENDING_RANGE, 'key', 'group', '-', '+', 1), ['XPENDING', 'key', 'group', '-', '+', '1'] ); }); it('with IDLE', () => { assert.deepEqual( - XPENDING_RANGE.transformArguments('key', 'group', '-', '+', 1, { + parseArgs(XPENDING_RANGE, 'key', 'group', '-', '+', 1, { IDLE: 1, }), ['XPENDING', 'key', 'group', 'IDLE', '1', '-', '+', '1'] @@ -22,7 +23,7 @@ describe('XPENDING RANGE', () => { it('with consumer', () => { assert.deepEqual( - XPENDING_RANGE.transformArguments('key', 'group', '-', '+', 1, { + parseArgs(XPENDING_RANGE, 'key', 'group', '-', '+', 1, { consumer: 'consumer' }), ['XPENDING', 'key', 'group', '-', '+', '1', 'consumer'] @@ -31,7 +32,7 @@ describe('XPENDING RANGE', () => { it('with IDLE, consumer', () => { assert.deepEqual( - XPENDING_RANGE.transformArguments('key', 'group', '-', '+', 1, { + parseArgs(XPENDING_RANGE, 'key', 'group', '-', '+', 1, { IDLE: 1, consumer: 'consumer' }), diff --git a/packages/client/lib/commands/XPENDING_RANGE.ts b/packages/client/lib/commands/XPENDING_RANGE.ts index 60a28e5172..8d98ffe7f1 100644 --- a/packages/client/lib/commands/XPENDING_RANGE.ts +++ b/packages/client/lib/commands/XPENDING_RANGE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, NumberReply, UnwrapReply, Command } from '../RESP/types'; export interface XPendingRangeOptions { @@ -13,33 +14,30 @@ type XPendingRangeRawReply = ArrayReply>; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, group: RedisArgument, start: RedisArgument, end: RedisArgument, count: number, options?: XPendingRangeOptions - ) { - const args = ['XPENDING', key, group]; + ) { + parser.push('XPENDING'); + parser.pushKey(key); + parser.push(group); if (options?.IDLE !== undefined) { - args.push('IDLE', options.IDLE.toString()); + parser.push('IDLE', options.IDLE.toString()); } - args.push( - start, - end, - count.toString() - ); + parser.push(start, end, count.toString()); if (options?.consumer) { - args.push(options.consumer); + parser.push(options.consumer); } - - return args; }, transformReply(reply: UnwrapReply) { return reply.map(pending => { diff --git a/packages/client/lib/commands/XRANGE.spec.ts b/packages/client/lib/commands/XRANGE.spec.ts index ebfe271db8..b111a97aff 100644 --- a/packages/client/lib/commands/XRANGE.spec.ts +++ b/packages/client/lib/commands/XRANGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XRANGE from './XRANGE'; +import { parseArgs } from './generic-transformers'; describe('XRANGE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XRANGE.transformArguments('key', '-', '+'), + parseArgs(XRANGE, 'key', '-', '+'), ['XRANGE', 'key', '-', '+'] ); }); it('with COUNT', () => { assert.deepEqual( - XRANGE.transformArguments('key', '-', '+', { + parseArgs(XRANGE, 'key', '-', '+', { COUNT: 1 }), ['XRANGE', 'key', '-', '+', 'COUNT', '1'] diff --git a/packages/client/lib/commands/XRANGE.ts b/packages/client/lib/commands/XRANGE.ts index fb65160d81..de6bb6c9b1 100644 --- a/packages/client/lib/commands/XRANGE.ts +++ b/packages/client/lib/commands/XRANGE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; import { StreamMessageRawReply, transformStreamMessageReply } from './generic-transformers'; @@ -5,14 +6,12 @@ export interface XRangeOptions { COUNT?: number; } -export function transformXRangeArguments( - command: RedisArgument, - key: RedisArgument, +export function xRangeArguments( start: RedisArgument, end: RedisArgument, options?: XRangeOptions ) { - const args = [command, key, start, end]; + const args = [start, end]; if (options?.COUNT) { args.push('COUNT', options.COUNT.toString()); @@ -22,9 +21,13 @@ export function transformXRangeArguments( } export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments: transformXRangeArguments.bind(undefined, 'XRANGE'), + parseCommand(parser: CommandParser, key: RedisArgument, ...args: Parameters) { + parser.push('XRANGE'); + parser.pushKey(key); + parser.pushVariadic(xRangeArguments(args[0], args[1], args[2])); + }, transformReply( reply: UnwrapReply>, preserve?: any, diff --git a/packages/client/lib/commands/XREAD.spec.ts b/packages/client/lib/commands/XREAD.spec.ts index 09784a56e6..bb72c96497 100644 --- a/packages/client/lib/commands/XREAD.spec.ts +++ b/packages/client/lib/commands/XREAD.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; -import testUtils, { GLOBAL } from '../test-utils'; +import testUtils, { GLOBAL, parseFirstKey } from '../test-utils'; import XREAD from './XREAD'; +import { parseArgs } from './generic-transformers'; describe('XREAD', () => { describe('FIRST_KEY_INDEX', () => { it('single stream', () => { assert.equal( - XREAD.FIRST_KEY_INDEX({ + parseFirstKey(XREAD, { key: 'key', id: '' }), @@ -16,7 +17,7 @@ describe('XREAD', () => { it('multiple streams', () => { assert.equal( - XREAD.FIRST_KEY_INDEX([{ + parseFirstKey(XREAD, [{ key: '1', id: '' }, { @@ -31,7 +32,7 @@ describe('XREAD', () => { describe('transformArguments', () => { it('single stream', () => { assert.deepEqual( - XREAD.transformArguments({ + parseArgs(XREAD, { key: 'key', id: '0-0' }), @@ -41,7 +42,7 @@ describe('XREAD', () => { it('multiple streams', () => { assert.deepEqual( - XREAD.transformArguments([{ + parseArgs(XREAD, [{ key: '1', id: '0-0' }, { @@ -54,7 +55,7 @@ describe('XREAD', () => { it('with COUNT', () => { assert.deepEqual( - XREAD.transformArguments({ + parseArgs(XREAD, { key: 'key', id: '0-0' }, { @@ -66,7 +67,7 @@ describe('XREAD', () => { it('with BLOCK', () => { assert.deepEqual( - XREAD.transformArguments({ + parseArgs(XREAD, { key: 'key', id: '0-0' }, { @@ -78,7 +79,7 @@ describe('XREAD', () => { it('with COUNT, BLOCK', () => { assert.deepEqual( - XREAD.transformArguments({ + parseArgs(XREAD, { key: 'key', id: '0-0' }, { @@ -90,7 +91,6 @@ describe('XREAD', () => { }); }); - testUtils.testAll('client.xRead', async client => { const message = { field: 'value' }, [id, reply] = await Promise.all([ diff --git a/packages/client/lib/commands/XREAD.ts b/packages/client/lib/commands/XREAD.ts index 97679376c1..b57fb8f398 100644 --- a/packages/client/lib/commands/XREAD.ts +++ b/packages/client/lib/commands/XREAD.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { Command, RedisArgument, ReplyUnion } from '../RESP/types'; import { transformStreamsMessagesReplyResp2 } from './generic-transformers'; @@ -8,19 +9,19 @@ export interface XReadStream { export type XReadStreams = Array | XReadStream; -export function pushXReadStreams(args: Array, streams: XReadStreams) { - args.push('STREAMS'); +export function pushXReadStreams(parser: CommandParser, streams: XReadStreams) { + parser.push('STREAMS'); if (Array.isArray(streams)) { - const keysStart = args.length, - idsStart = keysStart + streams.length; for (let i = 0; i < streams.length; i++) { - const stream = streams[i]; - args[keysStart + i] = stream.key; - args[idsStart + i] = stream.id; + parser.pushKey(streams[i].key); + } + for (let i = 0; i < streams.length; i++) { + parser.push(streams[i].id); } } else { - args.push(streams.key, streams.id); + parser.pushKey(streams.key); + parser.push(streams.id); } } @@ -30,24 +31,19 @@ export interface XReadOptions { } export default { - FIRST_KEY_INDEX(streams: XReadStreams) { - return Array.isArray(streams) ? streams[0].key : streams.key; - }, IS_READ_ONLY: true, - transformArguments(streams: XReadStreams, options?: XReadOptions) { - const args: Array = ['XREAD']; + parseCommand(parser: CommandParser, streams: XReadStreams, options?: XReadOptions) { + parser.push('XREAD'); if (options?.COUNT) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } if (options?.BLOCK !== undefined) { - args.push('BLOCK', options.BLOCK.toString()); + parser.push('BLOCK', options.BLOCK.toString()); } - pushXReadStreams(args, streams); - - return args; + pushXReadStreams(parser, streams); }, transformReply: { 2: transformStreamsMessagesReplyResp2, @@ -55,4 +51,3 @@ export default { }, unstableResp3: true } as const satisfies Command; - diff --git a/packages/client/lib/commands/XREADGROUP.spec.ts b/packages/client/lib/commands/XREADGROUP.spec.ts index 004a48ddbe..085a67bc9b 100644 --- a/packages/client/lib/commands/XREADGROUP.spec.ts +++ b/packages/client/lib/commands/XREADGROUP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; -import testUtils, { GLOBAL } from '../test-utils'; +import testUtils, { GLOBAL, parseFirstKey } from '../test-utils'; import XREADGROUP from './XREADGROUP'; +import { parseArgs } from './generic-transformers'; describe('XREADGROUP', () => { describe('FIRST_KEY_INDEX', () => { it('single stream', () => { assert.equal( - XREADGROUP.FIRST_KEY_INDEX('', '', { key: 'key', id: '' }), + parseFirstKey(XREADGROUP, '', '', { key: 'key', id: '' }), 'key' ); }); it('multiple streams', () => { assert.equal( - XREADGROUP.FIRST_KEY_INDEX('', '', [{ key: '1', id: '' }, { key: '2', id: '' }]), + parseFirstKey(XREADGROUP, '', '', [{ key: '1', id: '' }, { key: '2', id: '' }]), '1' ); }); @@ -22,7 +23,7 @@ describe('XREADGROUP', () => { describe('transformArguments', () => { it('single stream', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', { + parseArgs(XREADGROUP, 'group', 'consumer', { key: 'key', id: '0-0' }), @@ -32,7 +33,7 @@ describe('XREADGROUP', () => { it('multiple streams', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', [{ + parseArgs(XREADGROUP, 'group', 'consumer', [{ key: '1', id: '0-0' }, { @@ -45,7 +46,7 @@ describe('XREADGROUP', () => { it('with COUNT', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', { + parseArgs(XREADGROUP, 'group', 'consumer', { key: 'key', id: '0-0' }, { @@ -57,7 +58,7 @@ describe('XREADGROUP', () => { it('with BLOCK', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', { + parseArgs(XREADGROUP, 'group', 'consumer', { key: 'key', id: '0-0' }, { @@ -69,7 +70,7 @@ describe('XREADGROUP', () => { it('with NOACK', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', { + parseArgs(XREADGROUP, 'group', 'consumer', { key: 'key', id: '0-0' }, { @@ -81,7 +82,7 @@ describe('XREADGROUP', () => { it('with COUNT, BLOCK, NOACK', () => { assert.deepEqual( - XREADGROUP.transformArguments('group', 'consumer', { + parseArgs(XREADGROUP, 'group', 'consumer', { key: 'key', id: '0-0' }, { diff --git a/packages/client/lib/commands/XREADGROUP.ts b/packages/client/lib/commands/XREADGROUP.ts index 296480f9e3..d0947e19a0 100644 --- a/packages/client/lib/commands/XREADGROUP.ts +++ b/packages/client/lib/commands/XREADGROUP.ts @@ -1,6 +1,7 @@ +import { CommandParser } from '../client/parser'; import { Command, RedisArgument, ReplyUnion } from '../RESP/types'; +import { XReadStreams, pushXReadStreams } from './XREAD'; import { transformStreamsMessagesReplyResp2 } from './generic-transformers'; -import XREAD, { XReadStreams, pushXReadStreams } from './XREAD'; export interface XReadGroupOptions { COUNT?: number; @@ -9,37 +10,29 @@ export interface XReadGroupOptions { } export default { - FIRST_KEY_INDEX( - _group: RedisArgument, - _consumer: RedisArgument, - streams: XReadStreams - ) { - return XREAD.FIRST_KEY_INDEX(streams); - }, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, group: RedisArgument, consumer: RedisArgument, streams: XReadStreams, options?: XReadGroupOptions ) { - const args = ['XREADGROUP', 'GROUP', group, consumer]; + parser.push('XREADGROUP', 'GROUP', group, consumer); if (options?.COUNT !== undefined) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } if (options?.BLOCK !== undefined) { - args.push('BLOCK', options.BLOCK.toString()); + parser.push('BLOCK', options.BLOCK.toString()); } if (options?.NOACK) { - args.push('NOACK'); + parser.push('NOACK'); } - pushXReadStreams(args, streams); - - return args; + pushXReadStreams(parser, streams); }, transformReply: { 2: transformStreamsMessagesReplyResp2, diff --git a/packages/client/lib/commands/XREVRANGE.spec.ts b/packages/client/lib/commands/XREVRANGE.spec.ts index c9f3043af3..9872dc5e9e 100644 --- a/packages/client/lib/commands/XREVRANGE.spec.ts +++ b/packages/client/lib/commands/XREVRANGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XREVRANGE from './XREVRANGE'; +import { parseArgs } from './generic-transformers'; describe('XREVRANGE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XREVRANGE.transformArguments('key', '-', '+'), + parseArgs(XREVRANGE, 'key', '-', '+'), ['XREVRANGE', 'key', '-', '+'] ); }); it('with COUNT', () => { assert.deepEqual( - XREVRANGE.transformArguments('key', '-', '+', { + parseArgs(XREVRANGE, 'key', '-', '+', { COUNT: 1 }), ['XREVRANGE', 'key', '-', '+', 'COUNT', '1'] diff --git a/packages/client/lib/commands/XREVRANGE.ts b/packages/client/lib/commands/XREVRANGE.ts index 86e4d8abc9..ddc51082a1 100644 --- a/packages/client/lib/commands/XREVRANGE.ts +++ b/packages/client/lib/commands/XREVRANGE.ts @@ -1,13 +1,18 @@ -import { Command } from '../RESP/types'; -import XRANGE, { transformXRangeArguments } from './XRANGE'; +import { CommandParser } from '../client/parser'; +import { Command, RedisArgument } from '../RESP/types'; +import XRANGE, { xRangeArguments } from './XRANGE'; export interface XRevRangeOptions { COUNT?: number; } export default { - FIRST_KEY_INDEX: XRANGE.FIRST_KEY_INDEX, + CACHEABLE: XRANGE.CACHEABLE, IS_READ_ONLY: XRANGE.IS_READ_ONLY, - transformArguments: transformXRangeArguments.bind(undefined, 'XREVRANGE'), + parseCommand(parser: CommandParser, key: RedisArgument, ...args: Parameters) { + parser.push('XREVRANGE'); + parser.pushKey(key); + parser.pushVariadic(xRangeArguments(args[0], args[1], args[2])); + }, transformReply: XRANGE.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/XSETID.spec.ts b/packages/client/lib/commands/XSETID.spec.ts index 5ebbc94381..b360969534 100644 --- a/packages/client/lib/commands/XSETID.spec.ts +++ b/packages/client/lib/commands/XSETID.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XSETID from './XSETID'; +import { parseArgs } from './generic-transformers'; describe('XSETID', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XSETID.transformArguments('key', '0-0'), + parseArgs(XSETID, 'key', '0-0'), ['XSETID', 'key', '0-0'] ); }); it('with ENTRIESADDED', () => { assert.deepEqual( - XSETID.transformArguments('key', '0-0', { + parseArgs(XSETID, 'key', '0-0', { ENTRIESADDED: 1 }), ['XSETID', 'key', '0-0', 'ENTRIESADDED', '1'] @@ -22,7 +23,7 @@ describe('XSETID', () => { it('with MAXDELETEDID', () => { assert.deepEqual( - XSETID.transformArguments('key', '0-0', { + parseArgs(XSETID, 'key', '0-0', { MAXDELETEDID: '1-1' }), ['XSETID', 'key', '0-0', 'MAXDELETEDID', '1-1'] diff --git a/packages/client/lib/commands/XSETID.ts b/packages/client/lib/commands/XSETID.ts index a2ac8af001..c76ac0b23a 100644 --- a/packages/client/lib/commands/XSETID.ts +++ b/packages/client/lib/commands/XSETID.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../RESP/types'; export interface XSetIdOptions { /** added in 7.0 */ @@ -7,24 +8,24 @@ export interface XSetIdOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, lastId: RedisArgument, options?: XSetIdOptions ) { - const args = ['XSETID', key, lastId]; + parser.push('XSETID'); + parser.pushKey(key); + parser.push(lastId); if (options?.ENTRIESADDED) { - args.push('ENTRIESADDED', options.ENTRIESADDED.toString()); + parser.push('ENTRIESADDED', options.ENTRIESADDED.toString()); } if (options?.MAXDELETEDID) { - args.push('MAXDELETEDID', options.MAXDELETEDID); + parser.push('MAXDELETEDID', options.MAXDELETEDID); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/commands/XTRIM.spec.ts b/packages/client/lib/commands/XTRIM.spec.ts index a5a2fdf23c..2c31f0fef9 100644 --- a/packages/client/lib/commands/XTRIM.spec.ts +++ b/packages/client/lib/commands/XTRIM.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import XTRIM from './XTRIM'; +import { parseArgs } from './generic-transformers'; describe('XTRIM', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - XTRIM.transformArguments('key', 'MAXLEN', 1), + parseArgs(XTRIM, 'key', 'MAXLEN', 1), ['XTRIM', 'key', 'MAXLEN', '1'] ); }); it('with strategyModifier', () => { assert.deepEqual( - XTRIM.transformArguments('key', 'MAXLEN', 1, { + parseArgs(XTRIM, 'key', 'MAXLEN', 1, { strategyModifier: '=' }), ['XTRIM', 'key', 'MAXLEN', '=', '1'] @@ -22,7 +23,7 @@ describe('XTRIM', () => { it('with LIMIT', () => { assert.deepEqual( - XTRIM.transformArguments('key', 'MAXLEN', 1, { + parseArgs(XTRIM, 'key', 'MAXLEN', 1, { LIMIT: 1 }), ['XTRIM', 'key', 'MAXLEN', '1', 'LIMIT', '1'] @@ -31,7 +32,7 @@ describe('XTRIM', () => { it('with strategyModifier, LIMIT', () => { assert.deepEqual( - XTRIM.transformArguments('key', 'MAXLEN', 1, { + parseArgs(XTRIM, 'key', 'MAXLEN', 1, { strategyModifier: '=', LIMIT: 1 }), diff --git a/packages/client/lib/commands/XTRIM.ts b/packages/client/lib/commands/XTRIM.ts index 0512323a32..fb617d8d35 100644 --- a/packages/client/lib/commands/XTRIM.ts +++ b/packages/client/lib/commands/XTRIM.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; export interface XTrimOptions { @@ -7,27 +8,27 @@ export interface XTrimOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, strategy: 'MAXLEN' | 'MINID', threshold: number, options?: XTrimOptions ) { - const args = ['XTRIM', key, strategy]; + parser.push('XTRIM') + parser.pushKey(key); + parser.push(strategy); if (options?.strategyModifier) { - args.push(options.strategyModifier); + parser.push(options.strategyModifier); } - args.push(threshold.toString()); + parser.push(threshold.toString()); if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.toString()); + parser.push('LIMIT', options.LIMIT.toString()); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZADD.spec.ts b/packages/client/lib/commands/ZADD.spec.ts index 5f64cb13b9..0e770693e3 100644 --- a/packages/client/lib/commands/ZADD.spec.ts +++ b/packages/client/lib/commands/ZADD.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZADD from './ZADD'; +import { parseArgs } from './generic-transformers'; describe('ZADD', () => { describe('transformArguments', () => { it('single member', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }), @@ -16,7 +17,7 @@ describe('ZADD', () => { it('multiple members', () => { assert.deepEqual( - ZADD.transformArguments('key', [{ + parseArgs(ZADD, 'key', [{ value: '1', score: 1 }, { @@ -30,7 +31,7 @@ describe('ZADD', () => { describe('with condition', () => { it('condition property', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -42,7 +43,7 @@ describe('ZADD', () => { it('with NX (backwards compatibility)', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -54,7 +55,7 @@ describe('ZADD', () => { it('with XX (backwards compatibility)', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -68,7 +69,7 @@ describe('ZADD', () => { describe('with comparison', () => { it('with LT', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -80,7 +81,7 @@ describe('ZADD', () => { it('with LT (backwards compatibility)', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -92,7 +93,7 @@ describe('ZADD', () => { it('with GT (backwards compatibility)', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -105,7 +106,7 @@ describe('ZADD', () => { it('with CH', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { @@ -117,7 +118,7 @@ describe('ZADD', () => { it('with condition, comparison, CH', () => { assert.deepEqual( - ZADD.transformArguments('key', { + parseArgs(ZADD, 'key', { value: '1', score: 1 }, { diff --git a/packages/client/lib/commands/ZADD.ts b/packages/client/lib/commands/ZADD.ts index 0c5602bf98..5ae71a151b 100644 --- a/packages/client/lib/commands/ZADD.ts +++ b/packages/client/lib/commands/ZADD.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { SortedSetMember, transformDoubleArgument, transformDoubleReply } from './generic-transformers'; @@ -24,58 +25,57 @@ export interface ZAddOptions { } export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, members: SortedSetMember | Array, options?: ZAddOptions ) { - const args = ['ZADD', key]; + parser.push('ZADD'); + parser.pushKey(key); if (options?.condition) { - args.push(options.condition); + parser.push(options.condition); } else if (options?.NX) { - args.push('NX'); + parser.push('NX'); } else if (options?.XX) { - args.push('XX'); + parser.push('XX'); } if (options?.comparison) { - args.push(options.comparison); + parser.push(options.comparison); } else if (options?.LT) { - args.push('LT'); + parser.push('LT'); } else if (options?.GT) { - args.push('GT'); + parser.push('GT'); } if (options?.CH) { - args.push('CH'); + parser.push('CH'); } - pushMembers(args, members); - - return args; + pushMembers(parser, members); }, transformReply: transformDoubleReply } as const satisfies Command; export function pushMembers( - args: Array, + parser: CommandParser, members: SortedSetMember | Array) { if (Array.isArray(members)) { for (const member of members) { - pushMember(args, member); + pushMember(parser, member); } } else { - pushMember(args, members); + pushMember(parser, members); } } function pushMember( - args: Array, + parser: CommandParser, member: SortedSetMember ) { - args.push( + parser.push( transformDoubleArgument(member.score), member.value ); diff --git a/packages/client/lib/commands/ZADD_INCR.spec.ts b/packages/client/lib/commands/ZADD_INCR.spec.ts index c6ffcb796f..df9ac87f44 100644 --- a/packages/client/lib/commands/ZADD_INCR.spec.ts +++ b/packages/client/lib/commands/ZADD_INCR.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZADD_INCR from './ZADD_INCR'; +import { parseArgs } from './generic-transformers'; describe('ZADD INCR', () => { describe('transformArguments', () => { it('single member', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', { + parseArgs(ZADD_INCR, 'key', { value: '1', score: 1 }), @@ -16,7 +17,7 @@ describe('ZADD INCR', () => { it('multiple members', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', [{ + parseArgs(ZADD_INCR, 'key', [{ value: '1', score: 1 }, { @@ -29,7 +30,7 @@ describe('ZADD INCR', () => { it('with condition', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', { + parseArgs(ZADD_INCR, 'key', { value: '1', score: 1 }, { @@ -41,7 +42,7 @@ describe('ZADD INCR', () => { it('with comparison', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', { + parseArgs(ZADD_INCR, 'key', { value: '1', score: 1 }, { @@ -53,7 +54,7 @@ describe('ZADD INCR', () => { it('with CH', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', { + parseArgs(ZADD_INCR, 'key', { value: '1', score: 1 }, { @@ -65,7 +66,7 @@ describe('ZADD INCR', () => { it('with condition, comparison, CH', () => { assert.deepEqual( - ZADD_INCR.transformArguments('key', { + parseArgs(ZADD_INCR, 'key', { value: '1', score: 1 }, { diff --git a/packages/client/lib/commands/ZADD_INCR.ts b/packages/client/lib/commands/ZADD_INCR.ts index 8fb1072167..f37554b168 100644 --- a/packages/client/lib/commands/ZADD_INCR.ts +++ b/packages/client/lib/commands/ZADD_INCR.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { pushMembers } from './ZADD'; import { SortedSetMember, transformNullableDoubleReply } from './generic-transformers'; @@ -9,31 +10,30 @@ export interface ZAddOptions { } export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, members: SortedSetMember | Array, options?: ZAddOptions ) { - const args = ['ZADD', key]; + parser.push('ZADD'); + parser.pushKey(key); if (options?.condition) { - args.push(options.condition); + parser.push(options.condition); } if (options?.comparison) { - args.push(options.comparison); + parser.push(options.comparison); } if (options?.CH) { - args.push('CH'); + parser.push('CH'); } - args.push('INCR'); + parser.push('INCR'); - pushMembers(args, members); - - return args; + pushMembers(parser, members); }, transformReply: transformNullableDoubleReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZCARD.spec.ts b/packages/client/lib/commands/ZCARD.spec.ts index ff4bb881fb..44adec0833 100644 --- a/packages/client/lib/commands/ZCARD.spec.ts +++ b/packages/client/lib/commands/ZCARD.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZCARD from './ZCARD'; +import { parseArgs } from './generic-transformers'; describe('ZCARD', () => { it('transformArguments', () => { assert.deepEqual( - ZCARD.transformArguments('key'), + parseArgs(ZCARD, 'key'), ['ZCARD', 'key'] ); }); diff --git a/packages/client/lib/commands/ZCARD.ts b/packages/client/lib/commands/ZCARD.ts index c11cb69db3..57b9e7f1d4 100644 --- a/packages/client/lib/commands/ZCARD.ts +++ b/packages/client/lib/commands/ZCARD.ts @@ -1,10 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['ZCARD', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('ZCARD'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZCOUNT.spec.ts b/packages/client/lib/commands/ZCOUNT.spec.ts index 357f24bd79..5d279d7a4c 100644 --- a/packages/client/lib/commands/ZCOUNT.spec.ts +++ b/packages/client/lib/commands/ZCOUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZCOUNT from './ZCOUNT'; +import { parseArgs } from './generic-transformers'; describe('ZCOUNT', () => { it('transformArguments', () => { assert.deepEqual( - ZCOUNT.transformArguments('key', 0, 1), + parseArgs(ZCOUNT, 'key', 0, 1), ['ZCOUNT', 'key', '0', '1'] ); }); diff --git a/packages/client/lib/commands/ZCOUNT.ts b/packages/client/lib/commands/ZCOUNT.ts index 187a316b15..ccbc3d13d9 100644 --- a/packages/client/lib/commands/ZCOUNT.ts +++ b/packages/client/lib/commands/ZCOUNT.ts @@ -1,20 +1,22 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: number | RedisArgument, max: number | RedisArgument ) { - return [ - 'ZCOUNT', - key, - transformStringDoubleArgument(min), + parser.push('ZCOUNT'); + parser.pushKey(key); + parser.push( + transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZDIFF.spec.ts b/packages/client/lib/commands/ZDIFF.spec.ts index a285190398..4914df3e97 100644 --- a/packages/client/lib/commands/ZDIFF.spec.ts +++ b/packages/client/lib/commands/ZDIFF.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZDIFF from './ZDIFF'; +import { parseArgs } from './generic-transformers'; describe('ZDIFF', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('ZDIFF', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ZDIFF.transformArguments('key'), + parseArgs(ZDIFF, 'key'), ['ZDIFF', '1', 'key'] ); }); it('array', () => { assert.deepEqual( - ZDIFF.transformArguments(['1', '2']), + parseArgs(ZDIFF, ['1', '2']), ['ZDIFF', '2', '1', '2'] ); }); diff --git a/packages/client/lib/commands/ZDIFF.ts b/packages/client/lib/commands/ZDIFF.ts index f16c8717cd..28135dc9c1 100644 --- a/packages/client/lib/commands/ZDIFF.ts +++ b/packages/client/lib/commands/ZDIFF.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments(keys: RedisVariadicArgument) { - return pushVariadicArgument(['ZDIFF'], keys); + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + parser.push('ZDIFF'); + parser.pushKeysLength(keys); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZDIFFSTORE.spec.ts b/packages/client/lib/commands/ZDIFFSTORE.spec.ts index 1bd779302b..7f380cfc53 100644 --- a/packages/client/lib/commands/ZDIFFSTORE.spec.ts +++ b/packages/client/lib/commands/ZDIFFSTORE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZDIFFSTORE from './ZDIFFSTORE'; +import { parseArgs } from './generic-transformers'; describe('ZDIFFSTORE', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('ZDIFFSTORE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ZDIFFSTORE.transformArguments('destination', 'key'), + parseArgs(ZDIFFSTORE, 'destination', 'key'), ['ZDIFFSTORE', 'destination', '1', 'key'] ); }); it('array', () => { assert.deepEqual( - ZDIFFSTORE.transformArguments('destination', ['1', '2']), + parseArgs(ZDIFFSTORE, 'destination', ['1', '2']), ['ZDIFFSTORE', 'destination', '2', '1', '2'] ); }); diff --git a/packages/client/lib/commands/ZDIFFSTORE.ts b/packages/client/lib/commands/ZDIFFSTORE.ts index e4614a1cb1..d83a4bdc85 100644 --- a/packages/client/lib/commands/ZDIFFSTORE.ts +++ b/packages/client/lib/commands/ZDIFFSTORE.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( - destination: RedisArgument, - inputKeys: RedisVariadicArgument - ) { - return pushVariadicArgument(['ZDIFFSTORE', destination], inputKeys); + parseCommand(parser: CommandParser, destination: RedisArgument, inputKeys: RedisVariadicArgument) { + parser.push('ZDIFFSTORE'); + parser.pushKey(destination); + parser.pushKeysLength(inputKeys); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts b/packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts index 4fcd1f978a..bea639f223 100644 --- a/packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZDIFF_WITHSCORES from './ZDIFF_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZDIFF WITHSCORES', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('ZDIFF WITHSCORES', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ZDIFF_WITHSCORES.transformArguments('key'), + parseArgs(ZDIFF_WITHSCORES, 'key'), ['ZDIFF', '1', 'key', 'WITHSCORES'] ); }); it('array', () => { assert.deepEqual( - ZDIFF_WITHSCORES.transformArguments(['1', '2']), + parseArgs(ZDIFF_WITHSCORES, ['1', '2']), ['ZDIFF', '2', '1', '2', 'WITHSCORES'] ); }); diff --git a/packages/client/lib/commands/ZDIFF_WITHSCORES.ts b/packages/client/lib/commands/ZDIFF_WITHSCORES.ts index f971e82857..4088f106dc 100644 --- a/packages/client/lib/commands/ZDIFF_WITHSCORES.ts +++ b/packages/client/lib/commands/ZDIFF_WITHSCORES.ts @@ -1,14 +1,14 @@ +import { CommandParser } from '../client/parser'; import { Command } from '../RESP/types'; +import { RedisVariadicArgument, transformSortedSetReply } from './generic-transformers'; import ZDIFF from './ZDIFF'; -import { transformSortedSetReply } from './generic-transformers'; + export default { - FIRST_KEY_INDEX: ZDIFF.FIRST_KEY_INDEX, IS_READ_ONLY: ZDIFF.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZDIFF.transformArguments(...args); - redisArgs.push('WITHSCORES'); - return redisArgs; + parseCommand(parser: CommandParser, keys: RedisVariadicArgument) { + ZDIFF.parseCommand(parser, keys); + parser.push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZINCRBY.spec.ts b/packages/client/lib/commands/ZINCRBY.spec.ts index fea3c7a2f7..8f6c514125 100644 --- a/packages/client/lib/commands/ZINCRBY.spec.ts +++ b/packages/client/lib/commands/ZINCRBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZINCRBY from './ZINCRBY'; +import { parseArgs } from './generic-transformers'; describe('ZINCRBY', () => { it('transformArguments', () => { assert.deepEqual( - ZINCRBY.transformArguments('key', 1, 'member'), + parseArgs(ZINCRBY, 'key', 1, 'member'), ['ZINCRBY', 'key', '1', 'member'] ); }); diff --git a/packages/client/lib/commands/ZINCRBY.ts b/packages/client/lib/commands/ZINCRBY.ts index d9e4384501..5e461891e9 100644 --- a/packages/client/lib/commands/ZINCRBY.ts +++ b/packages/client/lib/commands/ZINCRBY.ts @@ -1,19 +1,17 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { transformDoubleArgument, transformDoubleReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, increment: number, member: RedisArgument ) { - return [ - 'ZINCRBY', - key, - transformDoubleArgument(increment), - member - ]; + parser.push('ZINCRBY'); + parser.pushKey(key); + parser.push(transformDoubleArgument(increment), member); }, transformReply: transformDoubleReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZINTER.spec.ts b/packages/client/lib/commands/ZINTER.spec.ts index 0d678ce115..73df0935de 100644 --- a/packages/client/lib/commands/ZINTER.spec.ts +++ b/packages/client/lib/commands/ZINTER.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZINTER from './ZINTER'; +import { parseArgs } from './generic-transformers'; describe('ZINTER', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,21 +9,21 @@ describe('ZINTER', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZINTER.transformArguments('key'), + parseArgs(ZINTER, 'key'), ['ZINTER', '1', 'key'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZINTER.transformArguments(['1', '2']), + parseArgs(ZINTER, ['1', '2']), ['ZINTER', '2', '1', '2'] ); }); it('key & weight', () => { assert.deepEqual( - ZINTER.transformArguments({ + parseArgs(ZINTER, { key: 'key', weight: 1 }), @@ -32,7 +33,7 @@ describe('ZINTER', () => { it('keys & weights', () => { assert.deepEqual( - ZINTER.transformArguments([{ + parseArgs(ZINTER, [{ key: 'a', weight: 1 }, { @@ -45,7 +46,7 @@ describe('ZINTER', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZINTER.transformArguments('key', { + parseArgs(ZINTER, 'key', { AGGREGATE: 'SUM' }), ['ZINTER', '1', 'key', 'AGGREGATE', 'SUM'] diff --git a/packages/client/lib/commands/ZINTER.ts b/packages/client/lib/commands/ZINTER.ts index 392c3a96c6..740d3c295e 100644 --- a/packages/client/lib/commands/ZINTER.ts +++ b/packages/client/lib/commands/ZINTER.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { ZKeys, pushZKeysArguments } from './generic-transformers'; +import { ZKeys, parseZKeysArguments } from './generic-transformers'; export type ZInterKeyAndWeight = { key: RedisArgument; @@ -8,32 +9,29 @@ export type ZInterKeyAndWeight = { export type ZInterKeys = T | [T, ...Array]; +export type ZInterKeysType = ZInterKeys | ZInterKeys; + export interface ZInterOptions { AGGREGATE?: 'SUM' | 'MIN' | 'MAX'; } -export function pushZInterArguments( - args: Array, +export function parseZInterArguments( + parser: CommandParser, keys: ZKeys, options?: ZInterOptions ) { - args = pushZKeysArguments(args, keys); + parseZKeysArguments(parser, keys); if (options?.AGGREGATE) { - args.push('AGGREGATE', options.AGGREGATE); + parser.push('AGGREGATE', options.AGGREGATE); } - - return args; } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( - keys: ZInterKeys | ZInterKeys, - options?: ZInterOptions - ) { - return pushZInterArguments(['ZINTER'], keys, options); + parseCommand(parser: CommandParser, keys: ZInterKeysType, options?: ZInterOptions) { + parser.push('ZINTER'); + parseZInterArguments(parser, keys, options); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZINTERCARD.spec.ts b/packages/client/lib/commands/ZINTERCARD.spec.ts index 312e2825ff..5204872a2d 100644 --- a/packages/client/lib/commands/ZINTERCARD.spec.ts +++ b/packages/client/lib/commands/ZINTERCARD.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZINTERCARD from './ZINTERCARD'; +import { parseArgs } from './generic-transformers'; describe('ZINTERCARD', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,7 +9,7 @@ describe('ZINTERCARD', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZINTERCARD.transformArguments(['1', '2']), + parseArgs(ZINTERCARD, ['1', '2']), ['ZINTERCARD', '2', '1', '2'] ); }); @@ -16,14 +17,14 @@ describe('ZINTERCARD', () => { describe('with LIMIT', () => { it('plain number (backwards compatibility)', () => { assert.deepEqual( - ZINTERCARD.transformArguments(['1', '2'], 1), + parseArgs(ZINTERCARD, ['1', '2'], 1), ['ZINTERCARD', '2', '1', '2', 'LIMIT', '1'] ); }); it('{ LIMIT: number }', () => { assert.deepEqual( - ZINTERCARD.transformArguments(['1', '2'], { + parseArgs(ZINTERCARD, ['1', '2'], { LIMIT: 1 }), ['ZINTERCARD', '2', '1', '2', 'LIMIT', '1'] diff --git a/packages/client/lib/commands/ZINTERCARD.ts b/packages/client/lib/commands/ZINTERCARD.ts index 9953d88eec..8c2e98d12c 100644 --- a/packages/client/lib/commands/ZINTERCARD.ts +++ b/packages/client/lib/commands/ZINTERCARD.ts @@ -1,27 +1,27 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export interface ZInterCardOptions { LIMIT?: number; } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, keys: RedisVariadicArgument, options?: ZInterCardOptions['LIMIT'] | ZInterCardOptions ) { - const args = pushVariadicArgument(['ZINTERCARD'], keys); + parser.push('ZINTERCARD'); + parser.pushKeysLength(keys); // backwards compatibility if (typeof options === 'number') { - args.push('LIMIT', options.toString()); + parser.push('LIMIT', options.toString()); } else if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.toString()); + parser.push('LIMIT', options.LIMIT.toString()); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZINTERSTORE.spec.ts b/packages/client/lib/commands/ZINTERSTORE.spec.ts index 27914ca032..c6b448ab90 100644 --- a/packages/client/lib/commands/ZINTERSTORE.spec.ts +++ b/packages/client/lib/commands/ZINTERSTORE.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZINTERSTORE from './ZINTERSTORE'; +import { parseArgs } from './generic-transformers'; describe('ZINTERSTORE', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZINTERSTORE.transformArguments('destination', 'source'), + parseArgs(ZINTERSTORE, 'destination', 'source'), ['ZINTERSTORE', 'destination', '1', 'source'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZINTERSTORE.transformArguments('destination', ['1', '2']), + parseArgs(ZINTERSTORE, 'destination', ['1', '2']), ['ZINTERSTORE', 'destination', '2', '1', '2'] ); }); it('key & weight', () => { assert.deepEqual( - ZINTERSTORE.transformArguments('destination', { + parseArgs(ZINTERSTORE, 'destination', { key: 'source', weight: 1 }), @@ -30,7 +31,7 @@ describe('ZINTERSTORE', () => { it('keys & weights', () => { assert.deepEqual( - ZINTERSTORE.transformArguments('destination', [{ + parseArgs(ZINTERSTORE, 'destination', [{ key: 'a', weight: 1 }, { @@ -43,7 +44,7 @@ describe('ZINTERSTORE', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZINTERSTORE.transformArguments('destination', 'source', { + parseArgs(ZINTERSTORE, 'destination', 'source', { AGGREGATE: 'SUM' }), ['ZINTERSTORE', 'destination', '1', 'source', 'AGGREGATE', 'SUM'] diff --git a/packages/client/lib/commands/ZINTERSTORE.ts b/packages/client/lib/commands/ZINTERSTORE.ts index a5334566d7..dcbe153cfc 100644 --- a/packages/client/lib/commands/ZINTERSTORE.ts +++ b/packages/client/lib/commands/ZINTERSTORE.ts @@ -1,17 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { pushZInterArguments, ZInterOptions } from './ZINTER'; import { ZKeys } from './generic-transformers'; +import { parseZInterArguments, ZInterOptions } from './ZINTER'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, keys: ZKeys, options?: ZInterOptions ) { - return pushZInterArguments(['ZINTERSTORE', destination], keys, options); + parser.push('ZINTERSTORE'); + parser.pushKey(destination); + parseZInterArguments(parser, keys, options); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts b/packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts index 05790510e4..234b250b14 100644 --- a/packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZINTER_WITHSCORES from './ZINTER_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZINTER WITHSCORES', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,21 +9,21 @@ describe('ZINTER WITHSCORES', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZINTER_WITHSCORES.transformArguments('key'), + parseArgs(ZINTER_WITHSCORES, 'key'), ['ZINTER', '1', 'key', 'WITHSCORES'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZINTER_WITHSCORES.transformArguments(['1', '2']), + parseArgs(ZINTER_WITHSCORES, ['1', '2']), ['ZINTER', '2', '1', '2', 'WITHSCORES'] ); }); it('key & weight', () => { assert.deepEqual( - ZINTER_WITHSCORES.transformArguments({ + parseArgs(ZINTER_WITHSCORES, { key: 'key', weight: 1 }), @@ -32,7 +33,7 @@ describe('ZINTER WITHSCORES', () => { it('keys & weights', () => { assert.deepEqual( - ZINTER_WITHSCORES.transformArguments([{ + parseArgs(ZINTER_WITHSCORES, [{ key: 'a', weight: 1 }, { @@ -45,7 +46,7 @@ describe('ZINTER WITHSCORES', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZINTER_WITHSCORES.transformArguments('key', { + parseArgs(ZINTER_WITHSCORES, 'key', { AGGREGATE: 'SUM' }), ['ZINTER', '1', 'key', 'AGGREGATE', 'SUM', 'WITHSCORES'] diff --git a/packages/client/lib/commands/ZINTER_WITHSCORES.ts b/packages/client/lib/commands/ZINTER_WITHSCORES.ts index b287649fbc..d3a6614b3c 100644 --- a/packages/client/lib/commands/ZINTER_WITHSCORES.ts +++ b/packages/client/lib/commands/ZINTER_WITHSCORES.ts @@ -1,14 +1,13 @@ import { Command } from '../RESP/types'; -import ZINTER from './ZINTER'; import { transformSortedSetReply } from './generic-transformers'; +import ZINTER from './ZINTER'; + export default { - FIRST_KEY_INDEX: ZINTER.FIRST_KEY_INDEX, IS_READ_ONLY: ZINTER.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZINTER.transformArguments(...args); - redisArgs.push('WITHSCORES'); - return redisArgs; + parseCommand(...args: Parameters) { + ZINTER.parseCommand(...args); + args[0].push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZLEXCOUNT.spec.ts b/packages/client/lib/commands/ZLEXCOUNT.spec.ts index d0a7607557..78c7411aff 100644 --- a/packages/client/lib/commands/ZLEXCOUNT.spec.ts +++ b/packages/client/lib/commands/ZLEXCOUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZLEXCOUNT from './ZLEXCOUNT'; +import { parseArgs } from './generic-transformers'; describe('ZLEXCOUNT', () => { it('transformArguments', () => { assert.deepEqual( - ZLEXCOUNT.transformArguments('key', '[a', '[b'), + parseArgs(ZLEXCOUNT, 'key', '[a', '[b'), ['ZLEXCOUNT', 'key', '[a', '[b'] ); }); diff --git a/packages/client/lib/commands/ZLEXCOUNT.ts b/packages/client/lib/commands/ZLEXCOUNT.ts index 26c9e0d70a..7536590c16 100644 --- a/packages/client/lib/commands/ZLEXCOUNT.ts +++ b/packages/client/lib/commands/ZLEXCOUNT.ts @@ -1,19 +1,19 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: RedisArgument, max: RedisArgument ) { - return [ - 'ZLEXCOUNT', - key, - min, - max - ]; + parser.push('ZLEXCOUNT'); + parser.pushKey(key); + parser.push(min); + parser.push(max); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZMPOP.spec.ts b/packages/client/lib/commands/ZMPOP.spec.ts index 6335fca81c..c15a53b731 100644 --- a/packages/client/lib/commands/ZMPOP.spec.ts +++ b/packages/client/lib/commands/ZMPOP.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZMPOP from './ZMPOP'; +import { parseArgs } from './generic-transformers'; describe('ZMPOP', () => { testUtils.isVersionGreaterThanHook([7]); @@ -8,14 +9,14 @@ describe('ZMPOP', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZMPOP.transformArguments('key', 'MIN'), + parseArgs(ZMPOP, 'key', 'MIN'), ['ZMPOP', '1', 'key', 'MIN'] ); }); it('with count', () => { assert.deepEqual( - ZMPOP.transformArguments('key', 'MIN', { + parseArgs(ZMPOP, 'key', 'MIN', { COUNT: 2 }), ['ZMPOP', '1', 'key', 'MIN', 'COUNT', '2'] diff --git a/packages/client/lib/commands/ZMPOP.ts b/packages/client/lib/commands/ZMPOP.ts index 57d2cccdac..0e47108e25 100644 --- a/packages/client/lib/commands/ZMPOP.ts +++ b/packages/client/lib/commands/ZMPOP.ts @@ -1,5 +1,6 @@ -import { RedisArgument, NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, UnwrapReply, Resp2Reply, Command, TypeMapping } from '../RESP/types'; -import { pushVariadicArgument, RedisVariadicArgument, SortedSetSide, transformSortedSetReply, transformDoubleReply } from './generic-transformers'; +import { CommandParser } from '../client/parser'; +import { NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, UnwrapReply, Resp2Reply, Command, TypeMapping } from '../RESP/types'; +import { RedisVariadicArgument, SortedSetSide, transformSortedSetReply, transformDoubleReply, Tail } from './generic-transformers'; export interface ZMPopOptions { COUNT?: number; @@ -13,30 +14,33 @@ export type ZMPopRawReply = NullReply | TuplesReply<[ ]>> ]>; -export function transformZMPopArguments( - args: Array, +export function parseZMPopArguments( + parser: CommandParser, keys: RedisVariadicArgument, side: SortedSetSide, options?: ZMPopOptions ) { - args = pushVariadicArgument(args, keys); + parser.pushKeysLength(keys); - args.push(side); + parser.push(side); if (options?.COUNT) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } - - return args; } -export type ZMPopArguments = typeof transformZMPopArguments extends (_: any, ...args: infer T) => any ? T : never; +export type ZMPopArguments = Tail>; export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments(...args: ZMPopArguments) { - return transformZMPopArguments(['ZMPOP'], ...args); + parseCommand( + parser: CommandParser, + keys: RedisVariadicArgument, + side: SortedSetSide, + options?: ZMPopOptions + ) { + parser.push('ZMPOP'); + parseZMPopArguments(parser, keys, side, options) }, transformReply: { 2(reply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) { diff --git a/packages/client/lib/commands/ZMSCORE.spec.ts b/packages/client/lib/commands/ZMSCORE.spec.ts index 5035724b11..6c6d2946e0 100644 --- a/packages/client/lib/commands/ZMSCORE.spec.ts +++ b/packages/client/lib/commands/ZMSCORE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZMSCORE from './ZMSCORE'; +import { parseArgs } from './generic-transformers'; describe('ZMSCORE', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('ZMSCORE', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ZMSCORE.transformArguments('key', 'member'), + parseArgs(ZMSCORE, 'key', 'member'), ['ZMSCORE', 'key', 'member'] ); }); it('array', () => { assert.deepEqual( - ZMSCORE.transformArguments('key', ['1', '2']), + parseArgs(ZMSCORE, 'key', ['1', '2']), ['ZMSCORE', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/ZMSCORE.ts b/packages/client/lib/commands/ZMSCORE.ts index 00ade13b01..b225b35dfd 100644 --- a/packages/client/lib/commands/ZMSCORE.ts +++ b/packages/client/lib/commands/ZMSCORE.ts @@ -1,14 +1,14 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, NullReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; -import { createTransformNullableDoubleReplyResp2Func, pushVariadicArguments, RedisVariadicArgument } from './generic-transformers'; +import { createTransformNullableDoubleReplyResp2Func, RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( - key: RedisArgument, - member: RedisVariadicArgument - ) { - return pushVariadicArguments(['ZMSCORE', key], member); + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisVariadicArgument) { + parser.push('ZMSCORE'); + parser.pushKey(key); + parser.pushVariadic(member); }, transformReply: { 2: (reply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/commands/ZPOPMAX.spec.ts b/packages/client/lib/commands/ZPOPMAX.spec.ts index 609ccb826b..1796647df8 100644 --- a/packages/client/lib/commands/ZPOPMAX.spec.ts +++ b/packages/client/lib/commands/ZPOPMAX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZPOPMAX from './ZPOPMAX'; +import { parseArgs } from './generic-transformers'; describe('ZPOPMAX', () => { it('transformArguments', () => { assert.deepEqual( - ZPOPMAX.transformArguments('key'), + parseArgs(ZPOPMAX, 'key'), ['ZPOPMAX', 'key'] ); }); diff --git a/packages/client/lib/commands/ZPOPMAX.ts b/packages/client/lib/commands/ZPOPMAX.ts index 130309347a..05c7f35e05 100644 --- a/packages/client/lib/commands/ZPOPMAX.ts +++ b/packages/client/lib/commands/ZPOPMAX.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, TuplesReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '../RESP/types'; import { transformDoubleReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument) { - return ['ZPOPMAX', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('ZPOPMAX'); + parser.pushKey(key); }, transformReply: { 2: (reply: UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts index b653b1f3f1..dd9d85dbd3 100644 --- a/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts +++ b/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZPOPMAX_COUNT from './ZPOPMAX_COUNT'; +import { parseArgs } from './generic-transformers'; describe('ZPOPMAX COUNT', () => { it('transformArguments', () => { assert.deepEqual( - ZPOPMAX_COUNT.transformArguments('key', 1), + parseArgs(ZPOPMAX_COUNT, 'key', 1), ['ZPOPMAX', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/ZPOPMAX_COUNT.ts b/packages/client/lib/commands/ZPOPMAX_COUNT.ts index 00d39536ae..888ce039fb 100644 --- a/packages/client/lib/commands/ZPOPMAX_COUNT.ts +++ b/packages/client/lib/commands/ZPOPMAX_COUNT.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { transformSortedSetReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, count: number) { - return ['ZPOPMAX', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('ZPOPMAX'); + parser.pushKey(key); + parser.push(count.toString()); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZPOPMIN.spec.ts b/packages/client/lib/commands/ZPOPMIN.spec.ts index 0b2c57d28b..653a4e70a9 100644 --- a/packages/client/lib/commands/ZPOPMIN.spec.ts +++ b/packages/client/lib/commands/ZPOPMIN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZPOPMIN from './ZPOPMIN'; +import { parseArgs } from './generic-transformers'; describe('ZPOPMIN', () => { it('transformArguments', () => { assert.deepEqual( - ZPOPMIN.transformArguments('key'), + parseArgs(ZPOPMIN, 'key'), ['ZPOPMIN', 'key'] ); }); diff --git a/packages/client/lib/commands/ZPOPMIN.ts b/packages/client/lib/commands/ZPOPMIN.ts index b9da85cc97..6295925aef 100644 --- a/packages/client/lib/commands/ZPOPMIN.ts +++ b/packages/client/lib/commands/ZPOPMIN.ts @@ -1,11 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import ZPOPMAX from './ZPOPMAX'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument) { - return ['ZPOPMIN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('ZPOPMIN'); + parser.pushKey(key); }, transformReply: ZPOPMAX.transformReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts index fa3d9e2a97..126a3cc1e9 100644 --- a/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts +++ b/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZPOPMIN_COUNT from './ZPOPMIN_COUNT'; +import { parseArgs } from './generic-transformers'; describe('ZPOPMIN COUNT', () => { it('transformArguments', () => { assert.deepEqual( - ZPOPMIN_COUNT.transformArguments('key', 1), + parseArgs(ZPOPMIN_COUNT, 'key', 1), ['ZPOPMIN', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/ZPOPMIN_COUNT.ts b/packages/client/lib/commands/ZPOPMIN_COUNT.ts index 2433686da5..2b6abf580b 100644 --- a/packages/client/lib/commands/ZPOPMIN_COUNT.ts +++ b/packages/client/lib/commands/ZPOPMIN_COUNT.ts @@ -1,11 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { transformSortedSetReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, count: number) { - return ['ZPOPMIN', key, count.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + parser.push('ZPOPMIN'); + parser.pushKey(key); + parser.push(count.toString()); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANDMEMBER.spec.ts b/packages/client/lib/commands/ZRANDMEMBER.spec.ts index 519850f5ef..a25ea79f8e 100644 --- a/packages/client/lib/commands/ZRANDMEMBER.spec.ts +++ b/packages/client/lib/commands/ZRANDMEMBER.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANDMEMBER from './ZRANDMEMBER'; +import { parseArgs } from './generic-transformers'; describe('ZRANDMEMBER', () => { testUtils.isVersionGreaterThanHook([6, 2]); it('transformArguments', () => { assert.deepEqual( - ZRANDMEMBER.transformArguments('key'), + parseArgs(ZRANDMEMBER, 'key'), ['ZRANDMEMBER', 'key'] ); }); diff --git a/packages/client/lib/commands/ZRANDMEMBER.ts b/packages/client/lib/commands/ZRANDMEMBER.ts index 449eb281c6..2abd9d3684 100644 --- a/packages/client/lib/commands/ZRANDMEMBER.ts +++ b/packages/client/lib/commands/ZRANDMEMBER.ts @@ -1,10 +1,11 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['ZRANDMEMBER', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('ZRANDMEMBER'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts index 2d0f4b9ced..eee0d45497 100644 --- a/packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts +++ b/packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANDMEMBER_COUNT from './ZRANDMEMBER_COUNT'; +import { parseArgs } from './generic-transformers'; describe('ZRANDMEMBER COUNT', () => { testUtils.isVersionGreaterThanHook([6, 2, 5]); it('transformArguments', () => { assert.deepEqual( - ZRANDMEMBER_COUNT.transformArguments('key', 1), + parseArgs(ZRANDMEMBER_COUNT, 'key', 1), ['ZRANDMEMBER', 'key', '1'] ); }); diff --git a/packages/client/lib/commands/ZRANDMEMBER_COUNT.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT.ts index 89b921f007..42ef811063 100644 --- a/packages/client/lib/commands/ZRANDMEMBER_COUNT.ts +++ b/packages/client/lib/commands/ZRANDMEMBER_COUNT.ts @@ -1,13 +1,12 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import ZRANDMEMBER from './ZRANDMEMBER'; export default { - FIRST_KEY_INDEX: ZRANDMEMBER.FIRST_KEY_INDEX, IS_READ_ONLY: ZRANDMEMBER.IS_READ_ONLY, - transformArguments(key: RedisArgument, count: number) { - const args = ZRANDMEMBER.transformArguments(key); - args.push(count.toString()); - return args; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + ZRANDMEMBER.parseCommand(parser, key); + parser.push(count.toString()); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts index aeeea3f6e7..3be3b92aee 100644 --- a/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANDMEMBER_COUNT_WITHSCORES from './ZRANDMEMBER_COUNT_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZRANDMEMBER COUNT WITHSCORES', () => { testUtils.isVersionGreaterThanHook([6, 2, 5]); it('transformArguments', () => { assert.deepEqual( - ZRANDMEMBER_COUNT_WITHSCORES.transformArguments('key', 1), + parseArgs(ZRANDMEMBER_COUNT_WITHSCORES, 'key', 1), ['ZRANDMEMBER', 'key', '1', 'WITHSCORES'] ); }); diff --git a/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts index 14c28d4b6c..f096e9d807 100644 --- a/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts +++ b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts @@ -1,14 +1,13 @@ +import { CommandParser } from '../client/parser'; import { Command, RedisArgument } from '../RESP/types'; -import ZRANDMEMBER_COUNT from './ZRANDMEMBER_COUNT'; import { transformSortedSetReply } from './generic-transformers'; +import ZRANDMEMBER_COUNT from './ZRANDMEMBER_COUNT'; export default { - FIRST_KEY_INDEX: ZRANDMEMBER_COUNT.FIRST_KEY_INDEX, IS_READ_ONLY: ZRANDMEMBER_COUNT.IS_READ_ONLY, - transformArguments(key: RedisArgument, count: number) { - const args = ZRANDMEMBER_COUNT.transformArguments(key, count); - args.push('WITHSCORES'); - return args; + parseCommand(parser: CommandParser, key: RedisArgument, count: number) { + ZRANDMEMBER_COUNT.parseCommand(parser, key, count); + parser.push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGE.spec.ts b/packages/client/lib/commands/ZRANGE.spec.ts index db940062b2..a780e4ef61 100644 --- a/packages/client/lib/commands/ZRANGE.spec.ts +++ b/packages/client/lib/commands/ZRANGE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGE from './ZRANGE'; +import { parseArgs } from './generic-transformers'; describe('ZRANGE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1), + parseArgs(ZRANGE, 'src', 0, 1), ['ZRANGE', 'src', '0', '1'] ); }); it('with BYSCORE', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1, { + parseArgs(ZRANGE, 'src', 0, 1, { BY: 'SCORE' }), ['ZRANGE', 'src', '0', '1', 'BYSCORE'] @@ -22,7 +23,7 @@ describe('ZRANGE', () => { it('with BYLEX', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1, { + parseArgs(ZRANGE, 'src', 0, 1, { BY: 'LEX' }), ['ZRANGE', 'src', '0', '1', 'BYLEX'] @@ -31,7 +32,7 @@ describe('ZRANGE', () => { it('with REV', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1, { + parseArgs(ZRANGE, 'src', 0, 1, { REV: true }), ['ZRANGE', 'src', '0', '1', 'REV'] @@ -40,7 +41,7 @@ describe('ZRANGE', () => { it('with LIMIT', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1, { + parseArgs(ZRANGE, 'src', 0, 1, { LIMIT: { offset: 0, count: 1 @@ -52,7 +53,7 @@ describe('ZRANGE', () => { it('with BY & REV & LIMIT', () => { assert.deepEqual( - ZRANGE.transformArguments('src', 0, 1, { + parseArgs(ZRANGE, 'src', 0, 1, { BY: 'SCORE', REV: true, LIMIT: { diff --git a/packages/client/lib/commands/ZRANGE.ts b/packages/client/lib/commands/ZRANGE.ts index 557044b67d..d1bc3433a5 100644 --- a/packages/client/lib/commands/ZRANGE.ts +++ b/packages/client/lib/commands/ZRANGE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; @@ -10,45 +11,54 @@ export interface ZRangeOptions { }; } +export function zRangeArgument( + min: RedisArgument | number, + max: RedisArgument | number, + options?: ZRangeOptions +) { + const args = [ + transformStringDoubleArgument(min), + transformStringDoubleArgument(max) + ] + + switch (options?.BY) { + case 'SCORE': + args.push('BYSCORE'); + break; + + case 'LEX': + args.push('BYLEX'); + break; + } + + if (options?.REV) { + args.push('REV'); + } + + if (options?.LIMIT) { + args.push( + 'LIMIT', + options.LIMIT.offset.toString(), + options.LIMIT.count.toString() + ); + } + + return args; +} + export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: RedisArgument | number, max: RedisArgument | number, options?: ZRangeOptions ) { - const args = [ - 'ZRANGE', - key, - transformStringDoubleArgument(min), - transformStringDoubleArgument(max) - ]; - - switch (options?.BY) { - case 'SCORE': - args.push('BYSCORE'); - break; - - case 'LEX': - args.push('BYLEX'); - break; - } - - if (options?.REV) { - args.push('REV'); - } - - if (options?.LIMIT) { - args.push( - 'LIMIT', - options.LIMIT.offset.toString(), - options.LIMIT.count.toString() - ); - } - - return args; + parser.push('ZRANGE'); + parser.pushKey(key); + parser.pushVariadic(zRangeArgument(min, max, options)) }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGEBYLEX.spec.ts b/packages/client/lib/commands/ZRANGEBYLEX.spec.ts index f3f6f4bc0e..942e184661 100644 --- a/packages/client/lib/commands/ZRANGEBYLEX.spec.ts +++ b/packages/client/lib/commands/ZRANGEBYLEX.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGEBYLEX from './ZRANGEBYLEX'; +import { parseArgs } from './generic-transformers'; describe('ZRANGEBYLEX', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGEBYLEX.transformArguments('src', '-', '+'), + parseArgs(ZRANGEBYLEX, 'src', '-', '+'), ['ZRANGEBYLEX', 'src', '-', '+'] ); }); it('with LIMIT', () => { assert.deepEqual( - ZRANGEBYLEX.transformArguments('src', '-', '+', { + parseArgs(ZRANGEBYLEX, 'src', '-', '+', { LIMIT: { offset: 0, count: 1 diff --git a/packages/client/lib/commands/ZRANGEBYLEX.ts b/packages/client/lib/commands/ZRANGEBYLEX.ts index afe7718f3c..316d9745c7 100644 --- a/packages/client/lib/commands/ZRANGEBYLEX.ts +++ b/packages/client/lib/commands/ZRANGEBYLEX.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; @@ -9,26 +10,25 @@ export interface ZRangeByLexOptions { } export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: RedisArgument, max: RedisArgument, options?: ZRangeByLexOptions ) { - const args = [ - 'ZRANGEBYLEX', - key, + parser.push('ZRANGEBYLEX'); + parser.pushKey(key); + parser.push( transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); + parser.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGEBYSCORE.spec.ts b/packages/client/lib/commands/ZRANGEBYSCORE.spec.ts index 61267ea7f2..364882f21a 100644 --- a/packages/client/lib/commands/ZRANGEBYSCORE.spec.ts +++ b/packages/client/lib/commands/ZRANGEBYSCORE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGEBYSCORE from './ZRANGEBYSCORE'; +import { parseArgs } from './generic-transformers'; describe('ZRANGEBYSCORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGEBYSCORE.transformArguments('src', 0, 1), + parseArgs(ZRANGEBYSCORE, 'src', 0, 1), ['ZRANGEBYSCORE', 'src', '0', '1'] ); }); it('with LIMIT', () => { assert.deepEqual( - ZRANGEBYSCORE.transformArguments('src', 0, 1, { + parseArgs(ZRANGEBYSCORE, 'src', 0, 1, { LIMIT: { offset: 0, count: 1 diff --git a/packages/client/lib/commands/ZRANGEBYSCORE.ts b/packages/client/lib/commands/ZRANGEBYSCORE.ts index e54c96380d..4d5471fdc0 100644 --- a/packages/client/lib/commands/ZRANGEBYSCORE.ts +++ b/packages/client/lib/commands/ZRANGEBYSCORE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; @@ -11,26 +12,25 @@ export interface ZRangeByScoreOptions { export declare function transformReply(): Array; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: string | number, max: string | number, options?: ZRangeByScoreOptions ) { - const args = [ - 'ZRANGEBYSCORE', - key, + parser.push('ZRANGEBYSCORE'); + parser.pushKey(key); + parser.push( transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); + parser.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts index e70a97b037..191eaa4e34 100644 --- a/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGEBYSCORE_WITHSCORES from './ZRANGEBYSCORE_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZRANGEBYSCORE WITHSCORES', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGEBYSCORE_WITHSCORES.transformArguments('src', 0, 1), + parseArgs(ZRANGEBYSCORE_WITHSCORES, 'src', 0, 1), ['ZRANGEBYSCORE', 'src', '0', '1', 'WITHSCORES'] ); }); it('with LIMIT', () => { assert.deepEqual( - ZRANGEBYSCORE_WITHSCORES.transformArguments('src', 0, 1, { + parseArgs(ZRANGEBYSCORE_WITHSCORES, 'src', 0, 1, { LIMIT: { offset: 0, count: 1 diff --git a/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts index bfbe09c6e2..1a759b23dc 100644 --- a/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts +++ b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts @@ -1,14 +1,15 @@ import { Command } from '../RESP/types'; -import ZRANGEBYSCORE from './ZRANGEBYSCORE'; import { transformSortedSetReply } from './generic-transformers'; +import ZRANGEBYSCORE from './ZRANGEBYSCORE'; export default { - FIRST_KEY_INDEX: ZRANGEBYSCORE.FIRST_KEY_INDEX, + CACHEABLE: ZRANGEBYSCORE.CACHEABLE, IS_READ_ONLY: ZRANGEBYSCORE.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZRANGEBYSCORE.transformArguments(...args); - redisArgs.push('WITHSCORES'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + + ZRANGEBYSCORE.parseCommand(...args); + parser.push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGESTORE.spec.ts b/packages/client/lib/commands/ZRANGESTORE.spec.ts index 51315d3463..c9708efd6f 100644 --- a/packages/client/lib/commands/ZRANGESTORE.spec.ts +++ b/packages/client/lib/commands/ZRANGESTORE.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGESTORE from './ZRANGESTORE'; +import { parseArgs } from './generic-transformers'; describe('ZRANGESTORE', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,14 +9,14 @@ describe('ZRANGESTORE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1), + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1), ['ZRANGESTORE', 'destination', 'source', '0', '1'] ); }); it('with BYSCORE', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1, { + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1, { BY: 'SCORE' }), ['ZRANGESTORE', 'destination', 'source', '0', '1', 'BYSCORE'] @@ -24,7 +25,7 @@ describe('ZRANGESTORE', () => { it('with BYLEX', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1, { + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1, { BY: 'LEX' }), ['ZRANGESTORE', 'destination', 'source', '0', '1', 'BYLEX'] @@ -33,7 +34,7 @@ describe('ZRANGESTORE', () => { it('with REV', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1, { + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1, { REV: true }), ['ZRANGESTORE', 'destination', 'source', '0', '1', 'REV'] @@ -42,7 +43,7 @@ describe('ZRANGESTORE', () => { it('with LIMIT', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1, { + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1, { LIMIT: { offset: 0, count: 1 @@ -54,7 +55,7 @@ describe('ZRANGESTORE', () => { it('with BY & REV & LIMIT', () => { assert.deepEqual( - ZRANGESTORE.transformArguments('destination', 'source', 0, 1, { + parseArgs(ZRANGESTORE, 'destination', 'source', 0, 1, { BY: 'SCORE', REV: true, LIMIT: { diff --git a/packages/client/lib/commands/ZRANGESTORE.ts b/packages/client/lib/commands/ZRANGESTORE.ts index 96f10120b8..f73e93a506 100644 --- a/packages/client/lib/commands/ZRANGESTORE.ts +++ b/packages/client/lib/commands/ZRANGESTORE.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; @@ -11,42 +12,40 @@ export interface ZRangeStoreOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, source: RedisArgument, min: RedisArgument | number, max: RedisArgument | number, options?: ZRangeStoreOptions ) { - const args = [ - 'ZRANGESTORE', - destination, - source, - transformStringDoubleArgument(min), + parser.push('ZRANGESTORE'); + parser.pushKey(destination); + parser.pushKey(source); + parser.push( + transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); switch (options?.BY) { case 'SCORE': - args.push('BYSCORE'); + parser.push('BYSCORE'); break; case 'LEX': - args.push('BYLEX'); + parser.push('BYLEX'); break; } if (options?.REV) { - args.push('REV'); + parser.push('REV'); } if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); + parser.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString()); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts index 038c150a67..e3009a6ead 100644 --- a/packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANGE_WITHSCORES from './ZRANGE_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZRANGE WITHSCORES', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ZRANGE_WITHSCORES.transformArguments('src', 0, 1), + parseArgs(ZRANGE_WITHSCORES, 'src', 0, 1), ['ZRANGE', 'src', '0', '1', 'WITHSCORES'] ); }); it('with BY', () => { assert.deepEqual( - ZRANGE_WITHSCORES.transformArguments('src', 0, 1, { + parseArgs(ZRANGE_WITHSCORES, 'src', 0, 1, { BY: 'SCORE' }), ['ZRANGE', 'src', '0', '1', 'BYSCORE', 'WITHSCORES'] @@ -22,7 +23,7 @@ describe('ZRANGE WITHSCORES', () => { it('with REV', () => { assert.deepEqual( - ZRANGE_WITHSCORES.transformArguments('src', 0, 1, { + parseArgs(ZRANGE_WITHSCORES, 'src', 0, 1, { REV: true }), ['ZRANGE', 'src', '0', '1', 'REV', 'WITHSCORES'] @@ -31,7 +32,7 @@ describe('ZRANGE WITHSCORES', () => { it('with LIMIT', () => { assert.deepEqual( - ZRANGE_WITHSCORES.transformArguments('src', 0, 1, { + parseArgs(ZRANGE_WITHSCORES, 'src', 0, 1, { LIMIT: { offset: 0, count: 1 @@ -43,7 +44,7 @@ describe('ZRANGE WITHSCORES', () => { it('with BY & REV & LIMIT', () => { assert.deepEqual( - ZRANGE_WITHSCORES.transformArguments('src', 0, 1, { + parseArgs(ZRANGE_WITHSCORES, 'src', 0, 1, { BY: 'SCORE', REV: true, LIMIT: { diff --git a/packages/client/lib/commands/ZRANGE_WITHSCORES.ts b/packages/client/lib/commands/ZRANGE_WITHSCORES.ts index cfa90e99ea..7e6cf00cf2 100644 --- a/packages/client/lib/commands/ZRANGE_WITHSCORES.ts +++ b/packages/client/lib/commands/ZRANGE_WITHSCORES.ts @@ -1,14 +1,15 @@ import { Command } from '../RESP/types'; -import ZRANGE from './ZRANGE'; import { transformSortedSetReply } from './generic-transformers'; +import ZRANGE from './ZRANGE'; export default { - FIRST_KEY_INDEX: ZRANGE.FIRST_KEY_INDEX, + CACHEABLE: ZRANGE.CACHEABLE, IS_READ_ONLY: ZRANGE.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZRANGE.transformArguments(...args); - redisArgs.push('WITHSCORES'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + + ZRANGE.parseCommand(...args); + parser.push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANK.spec.ts b/packages/client/lib/commands/ZRANK.spec.ts index 9341709bda..480f75f66e 100644 --- a/packages/client/lib/commands/ZRANK.spec.ts +++ b/packages/client/lib/commands/ZRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANK from './ZRANK'; +import { parseArgs } from './generic-transformers'; describe('ZRANK', () => { it('transformArguments', () => { assert.deepEqual( - ZRANK.transformArguments('key', 'member'), + parseArgs(ZRANK, 'key', 'member'), ['ZRANK', 'key', 'member'] ); }); diff --git a/packages/client/lib/commands/ZRANK.ts b/packages/client/lib/commands/ZRANK.ts index 11184c0a28..045e9ef8c2 100644 --- a/packages/client/lib/commands/ZRANK.ts +++ b/packages/client/lib/commands/ZRANK.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, NullReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, member: RedisArgument) { - return ['ZRANK', key, member]; + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisArgument) { + parser.push('ZRANK'); + parser.pushKey(key); + parser.push(member); }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZRANK_WITHSCORE.spec.ts b/packages/client/lib/commands/ZRANK_WITHSCORE.spec.ts index b571e0f707..9fa7cb1f6f 100644 --- a/packages/client/lib/commands/ZRANK_WITHSCORE.spec.ts +++ b/packages/client/lib/commands/ZRANK_WITHSCORE.spec.ts @@ -1,13 +1,14 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZRANK_WITHSCORE from './ZRANK_WITHSCORE'; +import { parseArgs } from './generic-transformers'; describe('ZRANK WITHSCORE', () => { testUtils.isVersionGreaterThanHook([7, 2]); it('transformArguments', () => { assert.deepEqual( - ZRANK_WITHSCORE.transformArguments('key', 'member'), + parseArgs(ZRANK_WITHSCORE, 'key', 'member'), ['ZRANK', 'key', 'member', 'WITHSCORE'] ); }); diff --git a/packages/client/lib/commands/ZRANK_WITHSCORE.ts b/packages/client/lib/commands/ZRANK_WITHSCORE.ts index 39c788535e..dc2e48b362 100644 --- a/packages/client/lib/commands/ZRANK_WITHSCORE.ts +++ b/packages/client/lib/commands/ZRANK_WITHSCORE.ts @@ -2,12 +2,13 @@ import { NullReply, TuplesReply, NumberReply, BlobStringReply, DoubleReply, Unwr import ZRANK from './ZRANK'; export default { - FIRST_KEY_INDEX: ZRANK.FIRST_KEY_INDEX, + CACHEABLE: ZRANK.CACHEABLE, IS_READ_ONLY: ZRANK.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZRANK.transformArguments(...args); - redisArgs.push('WITHSCORE'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + + ZRANK.parseCommand(...args); + parser.push('WITHSCORE'); }, transformReply: { 2: (reply: UnwrapReply>) => { diff --git a/packages/client/lib/commands/ZREM.spec.ts b/packages/client/lib/commands/ZREM.spec.ts index 4b203c9f4e..ac65b3d013 100644 --- a/packages/client/lib/commands/ZREM.spec.ts +++ b/packages/client/lib/commands/ZREM.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZREM from './ZREM'; +import { parseArgs } from './generic-transformers'; describe('ZREM', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - ZREM.transformArguments('key', 'member'), + parseArgs(ZREM, 'key', 'member'), ['ZREM', 'key', 'member'] ); }); it('array', () => { assert.deepEqual( - ZREM.transformArguments('key', ['1', '2']), + parseArgs(ZREM, 'key', ['1', '2']), ['ZREM', 'key', '1', '2'] ); }); diff --git a/packages/client/lib/commands/ZREM.ts b/packages/client/lib/commands/ZREM.ts index 54f55841fc..c8ba0ec02a 100644 --- a/packages/client/lib/commands/ZREM.ts +++ b/packages/client/lib/commands/ZREM.ts @@ -1,14 +1,17 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers'; +import { RedisVariadicArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, member: RedisVariadicArgument ) { - return pushVariadicArguments(['ZREM', key], member); + parser.push('ZREM'); + parser.pushKey(key); + parser.pushVariadic(member); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts b/packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts index 9f29c3cdcf..b141b7679e 100644 --- a/packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts +++ b/packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZREMRANGEBYLEX from './ZREMRANGEBYLEX'; +import { parseArgs } from './generic-transformers'; describe('ZREMRANGEBYLEX', () => { it('transformArguments', () => { assert.deepEqual( - ZREMRANGEBYLEX.transformArguments('key', '[a', '[b'), + parseArgs(ZREMRANGEBYLEX, 'key', '[a', '[b'), ['ZREMRANGEBYLEX', 'key', '[a', '[b'] ); }); diff --git a/packages/client/lib/commands/ZREMRANGEBYLEX.ts b/packages/client/lib/commands/ZREMRANGEBYLEX.ts index e3cd7013ac..5d7e1a21bb 100644 --- a/packages/client/lib/commands/ZREMRANGEBYLEX.ts +++ b/packages/client/lib/commands/ZREMRANGEBYLEX.ts @@ -1,20 +1,21 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, Command, RedisArgument } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: RedisArgument | number, max: RedisArgument | number ) { - return [ - 'ZREMRANGEBYLEX', - key, + parser.push('ZREMRANGEBYLEX'); + parser.pushKey(key); + parser.push( transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts b/packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts index 12627083e1..19f54466c2 100644 --- a/packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts +++ b/packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZREMRANGEBYRANK from './ZREMRANGEBYRANK'; +import { parseArgs } from './generic-transformers'; describe('ZREMRANGEBYRANK', () => { it('transformArguments', () => { assert.deepEqual( - ZREMRANGEBYRANK.transformArguments('key', 0, 1), + parseArgs(ZREMRANGEBYRANK, 'key', 0, 1), ['ZREMRANGEBYRANK', 'key', '0', '1'] ); }); diff --git a/packages/client/lib/commands/ZREMRANGEBYRANK.ts b/packages/client/lib/commands/ZREMRANGEBYRANK.ts index 986de33060..0a2eb3fadf 100644 --- a/packages/client/lib/commands/ZREMRANGEBYRANK.ts +++ b/packages/client/lib/commands/ZREMRANGEBYRANK.ts @@ -1,13 +1,20 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, start: number, - stop: number) { - return ['ZREMRANGEBYRANK', key, start.toString(), stop.toString()]; + stop: number + ) { + parser.push('ZREMRANGEBYRANK'); + parser.pushKey(key); + parser.push( + start.toString(), + stop.toString() + ); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts b/packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts index fb3ba4e718..856692ef8f 100644 --- a/packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts +++ b/packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import ZREMRANGEBYSCORE from './ZREMRANGEBYSCORE'; describe('ZREMRANGEBYSCORE', () => { it('transformArguments', () => { assert.deepEqual( - ZREMRANGEBYSCORE.transformArguments('key', 0, 1), + parseArgs(ZREMRANGEBYSCORE, 'key', 0, 1), ['ZREMRANGEBYSCORE', 'key', '0', '1'] ); }); diff --git a/packages/client/lib/commands/ZREMRANGEBYSCORE.ts b/packages/client/lib/commands/ZREMRANGEBYSCORE.ts index 7050f2627a..3d23d87594 100644 --- a/packages/client/lib/commands/ZREMRANGEBYSCORE.ts +++ b/packages/client/lib/commands/ZREMRANGEBYSCORE.ts @@ -1,20 +1,21 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command } from '../RESP/types'; import { transformStringDoubleArgument } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, min: RedisArgument | number, max: RedisArgument | number, ) { - return [ - 'ZREMRANGEBYSCORE', - key, + parser.push('ZREMRANGEBYSCORE'); + parser.pushKey(key); + parser.push( transformStringDoubleArgument(min), transformStringDoubleArgument(max) - ]; + ); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZREVRANK.spec.ts b/packages/client/lib/commands/ZREVRANK.spec.ts index 418773b600..c89f528eb1 100644 --- a/packages/client/lib/commands/ZREVRANK.spec.ts +++ b/packages/client/lib/commands/ZREVRANK.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import ZREVRANK from './ZREVRANK'; describe('ZREVRANK', () => { it('transformArguments', () => { assert.deepEqual( - ZREVRANK.transformArguments('key', 'member'), + parseArgs(ZREVRANK, 'key', 'member'), ['ZREVRANK', 'key', 'member'] ); }); diff --git a/packages/client/lib/commands/ZREVRANK.ts b/packages/client/lib/commands/ZREVRANK.ts index 3bf52d21de..d48dc68adc 100644 --- a/packages/client/lib/commands/ZREVRANK.ts +++ b/packages/client/lib/commands/ZREVRANK.ts @@ -1,10 +1,13 @@ +import { CommandParser } from '../client/parser'; import { NumberReply, NullReply, Command, RedisArgument } from '../RESP/types'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, member: RedisArgument) { - return ['ZREVRANK', key, member]; + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisArgument) { + parser.push('ZREVRANK'); + parser.pushKey(key); + parser.push(member); }, transformReply: undefined as unknown as () => NumberReply | NullReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZSCAN.spec.ts b/packages/client/lib/commands/ZSCAN.spec.ts index ebeaad2a4d..f8064aea41 100644 --- a/packages/client/lib/commands/ZSCAN.spec.ts +++ b/packages/client/lib/commands/ZSCAN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; +import { parseArgs } from './generic-transformers'; import ZSCAN from './ZSCAN'; describe('ZSCAN', () => { describe('transformArguments', () => { it('cusror only', () => { assert.deepEqual( - ZSCAN.transformArguments('key', '0'), + parseArgs(ZSCAN, 'key', '0'), ['ZSCAN', 'key', '0'] ); }); it('with MATCH', () => { assert.deepEqual( - ZSCAN.transformArguments('key', '0', { + parseArgs(ZSCAN, 'key', '0', { MATCH: 'pattern' }), ['ZSCAN', 'key', '0', 'MATCH', 'pattern'] @@ -22,7 +23,7 @@ describe('ZSCAN', () => { it('with COUNT', () => { assert.deepEqual( - ZSCAN.transformArguments('key', '0', { + parseArgs(ZSCAN, 'key', '0', { COUNT: 1 }), ['ZSCAN', 'key', '0', 'COUNT', '1'] @@ -31,7 +32,7 @@ describe('ZSCAN', () => { it('with MATCH & COUNT', () => { assert.deepEqual( - ZSCAN.transformArguments('key', '0', { + parseArgs(ZSCAN, 'key', '0', { MATCH: 'pattern', COUNT: 1 }), diff --git a/packages/client/lib/commands/ZSCAN.ts b/packages/client/lib/commands/ZSCAN.ts index 853cdf098f..051235033e 100644 --- a/packages/client/lib/commands/ZSCAN.ts +++ b/packages/client/lib/commands/ZSCAN.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { ScanCommonOptions, pushScanArguments } from './SCAN'; +import { ScanCommonOptions, parseScanArguments } from './SCAN'; import { transformSortedSetReply } from './generic-transformers'; export interface HScanEntry { @@ -8,14 +9,16 @@ export interface HScanEntry { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, cursor: RedisArgument, options?: ScanCommonOptions ) { - return pushScanArguments(['ZSCAN', key], cursor, options); + parser.push('ZSCAN'); + parser.pushKey(key); + parseScanArguments(parser, cursor, options); }, transformReply([cursor, rawMembers]: [BlobStringReply, ArrayReply]) { return { diff --git a/packages/client/lib/commands/ZSCORE.spec.ts b/packages/client/lib/commands/ZSCORE.spec.ts index 3d8df6640c..4229ab7aac 100644 --- a/packages/client/lib/commands/ZSCORE.spec.ts +++ b/packages/client/lib/commands/ZSCORE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZSCORE from './ZSCORE'; +import { parseArgs } from './generic-transformers'; describe('ZSCORE', () => { it('transformArguments', () => { assert.deepEqual( - ZSCORE.transformArguments('key', 'member'), + parseArgs(ZSCORE, 'key', 'member'), ['ZSCORE', 'key', 'member'] ); }); diff --git a/packages/client/lib/commands/ZSCORE.ts b/packages/client/lib/commands/ZSCORE.ts index 0d3db752e1..23b5290107 100644 --- a/packages/client/lib/commands/ZSCORE.ts +++ b/packages/client/lib/commands/ZSCORE.ts @@ -1,12 +1,15 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, Command } from '../RESP/types'; import { transformNullableDoubleReply } from './generic-transformers'; export default { - FIRST_KEY_INDEX: 1, + CACHEABLE: true, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, member: RedisArgument) { - return ['ZSCORE', key, member]; + parseCommand(parser: CommandParser, key: RedisArgument, member: RedisArgument) { + parser.push('ZSCORE'); + parser.pushKey(key); + parser.push(member); }, transformReply: transformNullableDoubleReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZUNION.spec.ts b/packages/client/lib/commands/ZUNION.spec.ts index f66bb7abc6..b4dbb4de60 100644 --- a/packages/client/lib/commands/ZUNION.spec.ts +++ b/packages/client/lib/commands/ZUNION.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZUNION from './ZUNION'; +import { parseArgs } from './generic-transformers'; describe('ZUNION', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,21 +9,21 @@ describe('ZUNION', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZUNION.transformArguments('key'), + parseArgs(ZUNION, 'key'), ['ZUNION', '1', 'key'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZUNION.transformArguments(['1', '2']), + parseArgs(ZUNION, ['1', '2']), ['ZUNION', '2', '1', '2'] ); }); it('key & weight', () => { assert.deepEqual( - ZUNION.transformArguments({ + parseArgs(ZUNION, { key: 'key', weight: 1 }), @@ -32,7 +33,7 @@ describe('ZUNION', () => { it('keys & weights', () => { assert.deepEqual( - ZUNION.transformArguments([{ + parseArgs(ZUNION, [{ key: 'a', weight: 1 }, { @@ -45,7 +46,7 @@ describe('ZUNION', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZUNION.transformArguments('key', { + parseArgs(ZUNION, 'key', { AGGREGATE: 'SUM' }), ['ZUNION', '1', 'key', 'AGGREGATE', 'SUM'] diff --git a/packages/client/lib/commands/ZUNION.ts b/packages/client/lib/commands/ZUNION.ts index 09614b9dc0..a91dc68bc0 100644 --- a/packages/client/lib/commands/ZUNION.ts +++ b/packages/client/lib/commands/ZUNION.ts @@ -1,24 +1,20 @@ +import { CommandParser } from '../client/parser'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; -import { ZKeys, pushZKeysArguments } from './generic-transformers'; +import { ZKeys, parseZKeysArguments } from './generic-transformers'; export interface ZUnionOptions { AGGREGATE?: 'SUM' | 'MIN' | 'MAX'; } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: true, - transformArguments( - keys: ZKeys, - options?: ZUnionOptions - ) { - const args = pushZKeysArguments(['ZUNION'], keys); + parseCommand(parser: CommandParser, keys: ZKeys, options?: ZUnionOptions) { + parser.push('ZUNION'); + parseZKeysArguments(parser, keys); if (options?.AGGREGATE) { - args.push('AGGREGATE', options.AGGREGATE); + parser.push('AGGREGATE', options.AGGREGATE); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZUNIONSTORE.spec.ts b/packages/client/lib/commands/ZUNIONSTORE.spec.ts index 7a01e80f0c..a369a64931 100644 --- a/packages/client/lib/commands/ZUNIONSTORE.spec.ts +++ b/packages/client/lib/commands/ZUNIONSTORE.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZUNIONSTORE from './ZUNIONSTORE'; +import { parseArgs } from './generic-transformers'; describe('ZUNIONSTORE', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZUNIONSTORE.transformArguments('destination', 'source'), + parseArgs(ZUNIONSTORE, 'destination', 'source'), ['ZUNIONSTORE', 'destination', '1', 'source'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZUNIONSTORE.transformArguments('destination', ['1', '2']), + parseArgs(ZUNIONSTORE, 'destination', ['1', '2']), ['ZUNIONSTORE', 'destination', '2', '1', '2'] ); }); it('key & weight', () => { assert.deepEqual( - ZUNIONSTORE.transformArguments('destination', { + parseArgs(ZUNIONSTORE, 'destination', { key: 'source', weight: 1 }), @@ -30,7 +31,7 @@ describe('ZUNIONSTORE', () => { it('keys & weights', () => { assert.deepEqual( - ZUNIONSTORE.transformArguments('destination', [{ + parseArgs(ZUNIONSTORE, 'destination', [{ key: 'a', weight: 1 }, { @@ -43,7 +44,7 @@ describe('ZUNIONSTORE', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZUNIONSTORE.transformArguments('destination', 'source', { + parseArgs(ZUNIONSTORE, 'destination', 'source', { AGGREGATE: 'SUM' }), ['ZUNIONSTORE', 'destination', '1', 'source', 'AGGREGATE', 'SUM'] diff --git a/packages/client/lib/commands/ZUNIONSTORE.ts b/packages/client/lib/commands/ZUNIONSTORE.ts index a14d3ba31c..c88f5a5a6f 100644 --- a/packages/client/lib/commands/ZUNIONSTORE.ts +++ b/packages/client/lib/commands/ZUNIONSTORE.ts @@ -1,25 +1,26 @@ +import { CommandParser } from '../client/parser'; import { RedisArgument, NumberReply, Command, } from '../RESP/types'; -import { ZKeys, pushZKeysArguments } from './generic-transformers'; +import { ZKeys, parseZKeysArguments } from './generic-transformers'; export interface ZUnionOptions { AGGREGATE?: 'SUM' | 'MIN' | 'MAX'; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, destination: RedisArgument, keys: ZKeys, options?: ZUnionOptions - ) { - const args = pushZKeysArguments(['ZUNIONSTORE', destination], keys); - + ): any { + parser.push('ZUNIONSTORE'); + parser.pushKey(destination); + parseZKeysArguments(parser, keys); + if (options?.AGGREGATE) { - args.push('AGGREGATE', options.AGGREGATE); + parser.push('AGGREGATE', options.AGGREGATE); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts b/packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts index bbf3ec676e..dee735fc99 100644 --- a/packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts +++ b/packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts @@ -1,6 +1,7 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ZUNION_WITHSCORES from './ZUNION_WITHSCORES'; +import { parseArgs } from './generic-transformers'; describe('ZUNION WITHSCORES', () => { testUtils.isVersionGreaterThanHook([6, 2]); @@ -8,21 +9,21 @@ describe('ZUNION WITHSCORES', () => { describe('transformArguments', () => { it('key (string)', () => { assert.deepEqual( - ZUNION_WITHSCORES.transformArguments('key'), + parseArgs(ZUNION_WITHSCORES, 'key'), ['ZUNION', '1', 'key', 'WITHSCORES'] ); }); it('keys (Array)', () => { assert.deepEqual( - ZUNION_WITHSCORES.transformArguments(['1', '2']), + parseArgs(ZUNION_WITHSCORES, ['1', '2']), ['ZUNION', '2', '1', '2', 'WITHSCORES'] ); }); it('key & weight', () => { assert.deepEqual( - ZUNION_WITHSCORES.transformArguments({ + parseArgs(ZUNION_WITHSCORES, { key: 'key', weight: 1 }), @@ -32,7 +33,7 @@ describe('ZUNION WITHSCORES', () => { it('keys & weights', () => { assert.deepEqual( - ZUNION_WITHSCORES.transformArguments([{ + parseArgs(ZUNION_WITHSCORES, [{ key: 'a', weight: 1 }, { @@ -45,7 +46,7 @@ describe('ZUNION WITHSCORES', () => { it('with AGGREGATE', () => { assert.deepEqual( - ZUNION_WITHSCORES.transformArguments('key', { + parseArgs(ZUNION_WITHSCORES, 'key', { AGGREGATE: 'SUM' }), ['ZUNION', '1', 'key', 'AGGREGATE', 'SUM', 'WITHSCORES'] diff --git a/packages/client/lib/commands/ZUNION_WITHSCORES.ts b/packages/client/lib/commands/ZUNION_WITHSCORES.ts index d0895a3de7..c62df55518 100644 --- a/packages/client/lib/commands/ZUNION_WITHSCORES.ts +++ b/packages/client/lib/commands/ZUNION_WITHSCORES.ts @@ -1,14 +1,15 @@ import { Command } from '../RESP/types'; -import ZUNION from './ZUNION'; import { transformSortedSetReply } from './generic-transformers'; +import ZUNION from './ZUNION'; + export default { - FIRST_KEY_INDEX: ZUNION.FIRST_KEY_INDEX, IS_READ_ONLY: ZUNION.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = ZUNION.transformArguments(...args); - redisArgs.push('WITHSCORES'); - return redisArgs; + parseCommand(...args: Parameters) { + const parser = args[0]; + + ZUNION.parseCommand(...args); + parser.push('WITHSCORES'); }, transformReply: transformSortedSetReply } as const satisfies Command; diff --git a/packages/client/lib/commands/generic-transformers.ts b/packages/client/lib/commands/generic-transformers.ts index cc7100d90e..fc139a948e 100644 --- a/packages/client/lib/commands/generic-transformers.ts +++ b/packages/client/lib/commands/generic-transformers.ts @@ -1,5 +1,6 @@ +import { BasicCommandParser, CommandParser } from '../client/parser'; import { RESP_TYPES } from '../RESP/decoder'; -import { UnwrapReply, ArrayReply, BlobStringReply, BooleanReply, CommandArguments, DoubleReply, NullReply, NumberReply, RedisArgument, TuplesReply, MapReply, TypeMapping } from '../RESP/types'; +import { UnwrapReply, ArrayReply, BlobStringReply, BooleanReply, CommandArguments, DoubleReply, NullReply, NumberReply, RedisArgument, TuplesReply, MapReply, TypeMapping, Command } from '../RESP/types'; export function isNullReply(reply: unknown): reply is NullReply { return reply === null; @@ -107,6 +108,19 @@ export interface Stringable { toString(): string; } +export function transformTuplesToMap( + reply: UnwrapReply>, + func: (elem: any) => T, +) { + const message = Object.create(null); + + for (let i = 0; i < reply.length; i+= 2) { + message[reply[i].toString()] = func(reply[i + 1]); + } + + return message; +} + export function createTransformTuplesReplyFunc(preserve?: any, typeMapping?: TypeMapping) { return (reply: ArrayReply) => { return transformTuplesReply(reply, preserve, typeMapping); @@ -255,16 +269,16 @@ export function pushVariadicArgument( return args; } -export function pushOptionalVariadicArgument( - args: CommandArguments, +export function parseOptionalVariadicArgument( + parser: CommandParser, name: RedisArgument, value?: RedisVariadicArgument -): CommandArguments { - if (value === undefined) return args; +) { + if (value === undefined) return; - args.push(name); + parser.push(name); - return pushVariadicArgument(args, value); + parser.pushVariadicWithLength(value); } export enum CommandFlags { @@ -393,29 +407,27 @@ export interface SlotRange { end: number; } -function pushSlotRangeArguments( - args: CommandArguments, +function parseSlotRangeArguments( + parser: CommandParser, range: SlotRange ): void { - args.push( + parser.push( range.start.toString(), range.end.toString() ); } -export function pushSlotRangesArguments( - args: CommandArguments, +export function parseSlotRangesArguments( + parser: CommandParser, ranges: SlotRange | Array -): CommandArguments { +) { if (Array.isArray(ranges)) { for (const range of ranges) { - pushSlotRangeArguments(args, range); + parseSlotRangeArguments(parser, range); } } else { - pushSlotRangeArguments(args, ranges); + parseSlotRangeArguments(parser, ranges); } - - return args; } export type RawRangeReply = [ @@ -444,41 +456,36 @@ export type ZVariadicKeys = T | [T, ...Array]; export type ZKeys = ZVariadicKeys | ZVariadicKeys; -export function pushZKeysArguments( - args: CommandArguments, +export function parseZKeysArguments( + parser: CommandParser, keys: ZKeys ) { if (Array.isArray(keys)) { - args.push(keys.length.toString()); + parser.push(keys.length.toString()); if (keys.length) { if (isPlainKeys(keys)) { - args = args.concat(keys); + parser.pushKeys(keys); } else { - const start = args.length; - args[start + keys.length] = 'WEIGHTS'; for (let i = 0; i < keys.length; i++) { - const index = start + i; - args[index] = keys[i].key; - args[index + 1 + keys.length] = transformDoubleArgument(keys[i].weight); + parser.pushKey(keys[i].key) + } + parser.push('WEIGHTS'); + for (let i = 0; i < keys.length; i++) { + parser.push(transformDoubleArgument(keys[i].weight)); } } } } else { - args.push('1'); + parser.push('1'); if (isPlainKey(keys)) { - args.push(keys); + parser.pushKey(keys); } else { - args.push( - keys.key, - 'WEIGHTS', - transformDoubleArgument(keys.weight) - ); + parser.pushKey(keys.key); + parser.push('WEIGHTS', transformDoubleArgument(keys.weight)); } } - - return args; } function isPlainKey(key: RedisArgument | ZKeyAndWeight): key is RedisArgument { @@ -489,6 +496,22 @@ function isPlainKeys(keys: Array | Array): keys is return isPlainKey(keys[0]); } +export type Tail = T extends [infer Head, ...infer Tail] ? Tail : never; + +/** + * @deprecated + */ +export function parseArgs(command: Command, ...args: Array): CommandArguments { + const parser = new BasicCommandParser(); + command.parseCommand!(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + if (parser.preserve) { + redisArgs.preserve = parser.preserve; + } + return redisArgs; +} + export type StreamMessageRawReply = TuplesReply<[ id: BlobStringReply, message: ArrayReply diff --git a/packages/client/lib/multi-command.ts b/packages/client/lib/multi-command.ts index a3ff4c9940..3d45a02fb4 100644 --- a/packages/client/lib/multi-command.ts +++ b/packages/client/lib/multi-command.ts @@ -16,6 +16,12 @@ export interface RedisMultiQueuedCommand { } export default class RedisMultiCommand { + private readonly typeMapping?: TypeMapping; + + constructor(typeMapping?: TypeMapping) { + this.typeMapping = typeMapping; + } + readonly queue: Array = []; readonly scriptsInUse = new Set(); @@ -46,7 +52,7 @@ export default class RedisMultiCommand { this.addCommand(redisArgs, transformReply); } - transformReplies(rawReplies: Array, typeMapping?: TypeMapping): Array { + transformReplies(rawReplies: Array): Array { const errorIndexes: Array = [], replies = rawReplies.map((reply, i) => { if (reply instanceof ErrorReply) { @@ -55,7 +61,7 @@ export default class RedisMultiCommand { } const { transformReply, args } = this.queue[i]; - return transformReply ? transformReply(reply, args.preserve, typeMapping) : reply; + return transformReply ? transformReply(reply, args.preserve, this.typeMapping) : reply; }); if (errorIndexes.length) throw new MultiErrorReply(replies, errorIndexes); diff --git a/packages/client/lib/sentinel/commands/SENTINEL_MASTER.ts b/packages/client/lib/sentinel/commands/SENTINEL_MASTER.ts index b260dcfba7..84997ac7d8 100644 --- a/packages/client/lib/sentinel/commands/SENTINEL_MASTER.ts +++ b/packages/client/lib/sentinel/commands/SENTINEL_MASTER.ts @@ -1,9 +1,10 @@ import { RedisArgument, MapReply, BlobStringReply, Command } from '../../RESP/types'; +import { CommandParser } from '../../client/parser'; import { transformTuplesReply } from '../../commands/generic-transformers'; export default { - transformArguments(dbname: RedisArgument) { - return ['SENTINEL', 'MASTER', dbname]; + parseCommand(parser: CommandParser, dbname: RedisArgument) { + parser.push('SENTINEL', 'MASTER', dbname); }, transformReply: { 2: transformTuplesReply, diff --git a/packages/client/lib/sentinel/commands/SENTINEL_MONITOR.ts b/packages/client/lib/sentinel/commands/SENTINEL_MONITOR.ts index 14caecd924..65f438de13 100644 --- a/packages/client/lib/sentinel/commands/SENTINEL_MONITOR.ts +++ b/packages/client/lib/sentinel/commands/SENTINEL_MONITOR.ts @@ -1,8 +1,9 @@ +import { CommandParser } from '../../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../../RESP/types'; export default { - transformArguments(dbname: RedisArgument, host: RedisArgument, port: RedisArgument, quorum: RedisArgument) { - return ['SENTINEL', 'MONITOR', dbname, host, port, quorum]; + parseCommand(parser: CommandParser, dbname: RedisArgument, host: RedisArgument, port: RedisArgument, quorum: RedisArgument) { + parser.push('SENTINEL', 'MONITOR', dbname, host, port, quorum); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/sentinel/commands/SENTINEL_REPLICAS.ts b/packages/client/lib/sentinel/commands/SENTINEL_REPLICAS.ts index 3d00289635..127449264d 100644 --- a/packages/client/lib/sentinel/commands/SENTINEL_REPLICAS.ts +++ b/packages/client/lib/sentinel/commands/SENTINEL_REPLICAS.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../../client/parser'; import { RedisArgument, ArrayReply, BlobStringReply, MapReply, Command, TypeMapping, UnwrapReply } from '../../RESP/types'; import { transformTuplesReply } from '../../commands/generic-transformers'; export default { - transformArguments(dbname: RedisArgument) { - return ['SENTINEL', 'REPLICAS', dbname]; + parseCommand(parser: CommandParser, dbname: RedisArgument) { + parser.push('SENTINEL', 'REPLICAS', dbname); }, transformReply: { 2: (reply: ArrayReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/sentinel/commands/SENTINEL_SENTINELS.ts b/packages/client/lib/sentinel/commands/SENTINEL_SENTINELS.ts index 22c1e0123f..4550b9498b 100644 --- a/packages/client/lib/sentinel/commands/SENTINEL_SENTINELS.ts +++ b/packages/client/lib/sentinel/commands/SENTINEL_SENTINELS.ts @@ -1,9 +1,10 @@ +import { CommandParser } from '../../client/parser'; import { RedisArgument, ArrayReply, MapReply, BlobStringReply, Command, TypeMapping, UnwrapReply } from '../../RESP/types'; import { transformTuplesReply } from '../../commands/generic-transformers'; export default { - transformArguments(dbname: RedisArgument) { - return ['SENTINEL', 'SENTINELS', dbname]; + parseCommand(parser: CommandParser, dbname: RedisArgument) { + parser.push('SENTINEL', 'SENTINELS', dbname); }, transformReply: { 2: (reply: ArrayReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/client/lib/sentinel/commands/SENTINEL_SET.ts b/packages/client/lib/sentinel/commands/SENTINEL_SET.ts index 4103781986..b4e8f843ea 100644 --- a/packages/client/lib/sentinel/commands/SENTINEL_SET.ts +++ b/packages/client/lib/sentinel/commands/SENTINEL_SET.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '../../client/parser'; import { RedisArgument, SimpleStringReply, Command } from '../../RESP/types'; export type SentinelSetOptions = Array<{ @@ -6,14 +7,12 @@ export type SentinelSetOptions = Array<{ }>; export default { - transformArguments(dbname: RedisArgument, options: SentinelSetOptions) { - const args = ['SENTINEL', 'SET', dbname]; + parseCommand(parser: CommandParser, dbname: RedisArgument, options: SentinelSetOptions) { + parser.push('SENTINEL', 'SET', dbname); for (const option of options) { - args.push(option.option, option.value); + parser.push(option.option, option.value); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/client/lib/sentinel/index.spec.ts b/packages/client/lib/sentinel/index.spec.ts index 1fba8d6b42..be5522bdd8 100644 --- a/packages/client/lib/sentinel/index.spec.ts +++ b/packages/client/lib/sentinel/index.spec.ts @@ -14,21 +14,10 @@ import { defineScript } from '../lua-script'; import { MATH_FUNCTION } from '../commands/FUNCTION_LOAD.spec'; import RedisBloomModules from '@redis/bloom'; import { RedisTcpSocketOptions } from '../client/socket'; +import { SQUARE_SCRIPT } from '../client/index.spec'; const execAsync = promisify(exec); -const SQUARE_SCRIPT = defineScript({ - SCRIPT: - `local number = redis.call('GET', KEYS[1]) - return number * number`, - NUMBER_OF_KEYS: 1, - FIRST_KEY_INDEX: 0, - transformArguments(key: string) { - return [key]; - }, - transformReply: undefined as unknown as () => NumberReply -}); - /* used to ensure test environment resets to normal state i.e. - all redis nodes are active and are part of the topology diff --git a/packages/client/lib/sentinel/index.ts b/packages/client/lib/sentinel/index.ts index b71514e935..d25fa03e55 100644 --- a/packages/client/lib/sentinel/index.ts +++ b/packages/client/lib/sentinel/index.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'node:events'; -import { CommandArguments, RedisArgument, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, TypeMapping } from '../RESP/types'; +import { CommandArguments, RedisFunctions, RedisModules, RedisScripts, ReplyUnion, RespVersions, TypeMapping } from '../RESP/types'; import RedisClient, { RedisClientOptions, RedisClientType } from '../client'; import { CommandOptions } from '../client/commands-queue'; import { attachConfig } from '../commander'; @@ -164,18 +164,6 @@ export class RedisSentinelClient< ); } - executeScript( - script: RedisScript, - isReadonly: boolean | undefined, - args: Array, - options?: CommandOptions - ) { - return this._execute( - isReadonly, - client => client.executeScript(script, args, options) - ); - } - /** * @internal */ @@ -440,18 +428,6 @@ export default class RedisSentinel< ); } - executeScript( - script: RedisScript, - isReadonly: boolean | undefined, - args: Array, - options?: CommandOptions - ) { - return this._execute( - isReadonly, - client => client.executeScript(script, args, options) - ); - } - /** * @internal */ diff --git a/packages/client/lib/sentinel/multi-commands.ts b/packages/client/lib/sentinel/multi-commands.ts index bf616370bf..e70dc45c79 100644 --- a/packages/client/lib/sentinel/multi-commands.ts +++ b/packages/client/lib/sentinel/multi-commands.ts @@ -3,6 +3,8 @@ import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../m import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types'; import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander'; import { RedisSentinelType } from './types'; +import { BasicCommandParser } from '../client/parser'; +import { Tail } from '../commands/generic-transformers'; type CommandSignature< REPLIES extends Array, @@ -12,7 +14,7 @@ type CommandSignature< S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping -> = (...args: Parameters) => RedisSentinelMultiCommandType< +> = (...args: Tail>) => RedisSentinelMultiCommandType< [...REPLIES, ReplyWithTypeMapping, TYPE_MAPPING>], M, F, @@ -87,8 +89,14 @@ export type RedisSentinelMultiCommandType< export default class RedisSentinelMultiCommand { private static _createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: RedisSentinelMultiCommand, ...args: Array) { - const redisArgs = command.transformArguments(...args); + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this.addCommand( command.IS_READ_ONLY, redisArgs, @@ -99,8 +107,14 @@ export default class RedisSentinelMultiCommand { private static _createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array) { - const redisArgs = command.transformArguments(...args); + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this._self.addCommand( command.IS_READ_ONLY, redisArgs, @@ -110,12 +124,17 @@ export default class RedisSentinelMultiCommand { } private static _createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); + return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const redisArgs: CommandArguments = prefix.concat(fnArgs); - redisArgs.preserve = fnArgs.preserve; + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); + + const redisArgs: CommandArguments = parser.redisArgs; + redisArgs.preserve = parser.preserve; + return this._self.addCommand( fn.IS_READ_ONLY, redisArgs, @@ -126,17 +145,20 @@ export default class RedisSentinelMultiCommand { private static _createScriptCommand(script: RedisScript, resp: RespVersions) { const transformReply = getTransformReply(script, resp); + return function (this: RedisSentinelMultiCommand, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - this._setState( - script.IS_READ_ONLY - ); - this._multi.addScript( + const parser = new BasicCommandParser(); + script.parseCommand(parser, ...args); + + const scriptArgs: CommandArguments = parser.redisArgs; + scriptArgs.preserve = parser.preserve; + + return this.#addScript( + script.IS_READ_ONLY, script, scriptArgs, transformReply ); - return this; }; } @@ -157,20 +179,19 @@ export default class RedisSentinelMultiCommand { }); } - private readonly _multi = new RedisMultiCommand(); - private readonly _sentinel: RedisSentinelType - private _isReadonly: boolean | undefined = true; - private readonly _typeMapping?: TypeMapping; + readonly #multi = new RedisMultiCommand(); + readonly #sentinel: RedisSentinelType + #isReadonly: boolean | undefined = true; constructor(sentinel: RedisSentinelType, typeMapping: TypeMapping) { - this._sentinel = sentinel; - this._typeMapping = typeMapping; + this.#multi = new RedisMultiCommand(typeMapping); + this.#sentinel = sentinel; } - private _setState( + #setState( isReadonly: boolean | undefined, ) { - this._isReadonly &&= isReadonly; + this.#isReadonly &&= isReadonly; } addCommand( @@ -178,20 +199,31 @@ export default class RedisSentinelMultiCommand { args: CommandArguments, transformReply?: TransformReply ) { - this._setState(isReadonly); - this._multi.addCommand(args, transformReply); + this.#setState(isReadonly); + this.#multi.addCommand(args, transformReply); + return this; + } + + #addScript( + isReadonly: boolean | undefined, + script: RedisScript, + args: CommandArguments, + transformReply?: TransformReply + ) { + this.#setState(isReadonly); + this.#multi.addScript(script, args, transformReply); + return this; } async exec(execAsPipeline = false) { if (execAsPipeline) return this.execAsPipeline(); - return this._multi.transformReplies( - await this._sentinel._executeMulti( - this._isReadonly, - this._multi.queue - ), - this._typeMapping + return this.#multi.transformReplies( + await this.#sentinel._executeMulti( + this.#isReadonly, + this.#multi.queue + ) ) as MultiReplyType; } @@ -202,14 +234,13 @@ export default class RedisSentinelMultiCommand { } async execAsPipeline() { - if (this._multi.queue.length === 0) return [] as MultiReplyType; - - return this._multi.transformReplies( - await this._sentinel._executePipeline( - this._isReadonly, - this._multi.queue - ), - this._typeMapping + if (this.#multi.queue.length === 0) return [] as MultiReplyType; + + return this.#multi.transformReplies( + await this.#sentinel._executePipeline( + this.#isReadonly, + this.#multi.queue + ) ) as MultiReplyType; } diff --git a/packages/client/lib/sentinel/utils.ts b/packages/client/lib/sentinel/utils.ts index b4d430b1b4..90b789ddca 100644 --- a/packages/client/lib/sentinel/utils.ts +++ b/packages/client/lib/sentinel/utils.ts @@ -1,3 +1,4 @@ +import { BasicCommandParser } from '../client/parser'; import { ArrayReply, Command, RedisFunction, RedisScript, RespVersions, UnwrapReply } from '../RESP/types'; import { RedisSocketOptions, RedisTcpSocketOptions } from '../client/socket'; import { functionArgumentsPrefix, getTransformReply, scriptArgumentsPrefix } from '../commander'; @@ -38,77 +39,60 @@ export function clientSocketToNode(socket: RedisSocketOptions): RedisNode { export function createCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return async function (this: T, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._self.commandOptions?.typeMapping; + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - const reply = await this._self.sendCommand( + return this._self._execute( command.IS_READ_ONLY, - redisArgs, - this._self.commandOptions + client => client._executeCommand(command, parser, this.commandOptions, transformReply) ); - - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; }; } export function createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) { - const prefix = functionArgumentsPrefix(name, fn), - transformReply = getTransformReply(fn, resp); + const prefix = functionArgumentsPrefix(name, fn); + const transformReply = getTransformReply(fn, resp); + return async function (this: T, ...args: Array) { - const fnArgs = fn.transformArguments(...args); - const redisArgs = prefix.concat(fnArgs); - const typeMapping = this._self._self.commandOptions?.typeMapping; + const parser = new BasicCommandParser(); + parser.push(...prefix); + fn.parseCommand(parser, ...args); - const reply = await this._self._self.sendCommand( + return this._self._execute( fn.IS_READ_ONLY, - redisArgs, - this._self._self.commandOptions + client => client._executeCommand(fn, parser, this._self.commandOptions, transformReply) ); - - return transformReply ? - transformReply(reply, fnArgs.preserve, typeMapping) : - reply; } }; export function createModuleCommand(command: Command, resp: RespVersions) { const transformReply = getTransformReply(command, resp); + return async function (this: T, ...args: Array) { - const redisArgs = command.transformArguments(...args); - const typeMapping = this._self._self.commandOptions?.typeMapping; + const parser = new BasicCommandParser(); + command.parseCommand(parser, ...args); - const reply = await this._self._self.sendCommand( + return this._self._execute( command.IS_READ_ONLY, - redisArgs, - this._self._self.commandOptions + client => client._executeCommand(command, parser, this._self.commandOptions, transformReply) ); - - return transformReply ? - transformReply(reply, redisArgs.preserve, typeMapping) : - reply; } }; export function createScriptCommand(script: RedisScript, resp: RespVersions) { - const prefix = scriptArgumentsPrefix(script), - transformReply = getTransformReply(script, resp); + const prefix = scriptArgumentsPrefix(script); + const transformReply = getTransformReply(script, resp); + return async function (this: T, ...args: Array) { - const scriptArgs = script.transformArguments(...args); - const redisArgs = prefix.concat(scriptArgs); - const typeMapping = this._self.commandOptions?.typeMapping; + const parser = new BasicCommandParser(); + parser.push(...prefix); + script.parseCommand(parser, ...args); - const reply = await this._self.executeScript( - script, + return this._self._execute( script.IS_READ_ONLY, - redisArgs, - this._self.commandOptions + client => client._executeScript(script, parser, this.commandOptions, transformReply) ); - - return transformReply ? - transformReply(reply, scriptArgs.preserve, typeMapping) : - reply; }; } diff --git a/packages/client/lib/test-utils.ts b/packages/client/lib/test-utils.ts index 29eb03cb73..083c9127e5 100644 --- a/packages/client/lib/test-utils.ts +++ b/packages/client/lib/test-utils.ts @@ -1,6 +1,8 @@ import TestUtils from '@redis/test-utils'; import { SinonSpy } from 'sinon'; import { setTimeout } from 'node:timers/promises'; +import { Command } from './RESP/types'; +import { BasicCommandParser } from './client/parser'; const utils = new TestUtils({ dockerImageName: 'redis/redis-stack', @@ -67,3 +69,9 @@ export const BLOCKING_MIN_VALUE = ( utils.isVersionGreaterThan([6]) ? 0.01 : 1 ); + +export function parseFirstKey(command: Command, ...args: Array) { + const parser = new BasicCommandParser(); + command.parseCommand!(parser, ...args); + return parser.firstKey; +} diff --git a/packages/graph/lib/commands/CONFIG_GET.spec.ts b/packages/graph/lib/commands/CONFIG_GET.spec.ts index 42c7739f5d..9a427867c6 100644 --- a/packages/graph/lib/commands/CONFIG_GET.spec.ts +++ b/packages/graph/lib/commands/CONFIG_GET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_GET from './CONFIG_GET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.CONFIG GET', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_GET.transformArguments('TIMEOUT'), + parseArgs(CONFIG_GET, 'TIMEOUT'), ['GRAPH.CONFIG', 'GET', 'TIMEOUT'] ); }); diff --git a/packages/graph/lib/commands/CONFIG_GET.ts b/packages/graph/lib/commands/CONFIG_GET.ts index c7ed037e1a..8ff289876d 100644 --- a/packages/graph/lib/commands/CONFIG_GET.ts +++ b/packages/graph/lib/commands/CONFIG_GET.ts @@ -1,4 +1,5 @@ -import { RedisArgument, TuplesReply, ArrayReply, BlobStringReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, TuplesReply, ArrayReply, BlobStringReply, NumberReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; type ConfigItemReply = TuplesReply<[ configKey: BlobStringReply, @@ -6,10 +7,10 @@ type ConfigItemReply = TuplesReply<[ ]>; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(configKey: RedisArgument) { - return ['GRAPH.CONFIG', 'GET', configKey]; + parseCommand(parser: CommandParser, configKey: RedisArgument) { + parser.push('GRAPH.CONFIG', 'GET', configKey); }, transformReply: undefined as unknown as () => ConfigItemReply | ArrayReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/CONFIG_SET.spec.ts b/packages/graph/lib/commands/CONFIG_SET.spec.ts index 5ed51e78a2..ae6e296699 100644 --- a/packages/graph/lib/commands/CONFIG_SET.spec.ts +++ b/packages/graph/lib/commands/CONFIG_SET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_SET from './CONFIG_SET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.CONFIG SET', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_SET.transformArguments('TIMEOUT', 0), + parseArgs(CONFIG_SET, 'TIMEOUT', 0), ['GRAPH.CONFIG', 'SET', 'TIMEOUT', '0'] ); }); diff --git a/packages/graph/lib/commands/CONFIG_SET.ts b/packages/graph/lib/commands/CONFIG_SET.ts index ba23ac2f1a..b37d8690bf 100644 --- a/packages/graph/lib/commands/CONFIG_SET.ts +++ b/packages/graph/lib/commands/CONFIG_SET.ts @@ -1,15 +1,11 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(configKey: RedisArgument, value: number) { - return [ - 'GRAPH.CONFIG', - 'SET', - configKey, - value.toString() - ]; + parseCommand(parser: CommandParser, configKey: RedisArgument, value: number) { + parser.push('GRAPH.CONFIG', 'SET', configKey, value.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/graph/lib/commands/DELETE.spec.ts b/packages/graph/lib/commands/DELETE.spec.ts index 6fe24fd827..5977c64630 100644 --- a/packages/graph/lib/commands/DELETE.spec.ts +++ b/packages/graph/lib/commands/DELETE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DELETE from './DELETE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.DELETE', () => { it('transformArguments', () => { assert.deepEqual( - DELETE.transformArguments('key'), + parseArgs(DELETE, 'key'), ['GRAPH.DELETE', 'key'] ); }); diff --git a/packages/graph/lib/commands/DELETE.ts b/packages/graph/lib/commands/DELETE.ts index f5f99fb92c..2e1f9ff003 100644 --- a/packages/graph/lib/commands/DELETE.ts +++ b/packages/graph/lib/commands/DELETE.ts @@ -1,10 +1,11 @@ -import { RedisArgument, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument) { - return ['GRAPH.DELETE', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('GRAPH.DELETE'); + parser.pushKey(key); }, transformReply: undefined as unknown as () => BlobStringReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/EXPLAIN.spec.ts b/packages/graph/lib/commands/EXPLAIN.spec.ts index 04bf838a4d..28f30cd17b 100644 --- a/packages/graph/lib/commands/EXPLAIN.spec.ts +++ b/packages/graph/lib/commands/EXPLAIN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import EXPLAIN from './EXPLAIN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.EXPLAIN', () => { it('transformArguments', () => { assert.deepEqual( - EXPLAIN.transformArguments('key', 'RETURN 0'), + parseArgs(EXPLAIN, 'key', 'RETURN 0'), ['GRAPH.EXPLAIN', 'key', 'RETURN 0'] ); }); diff --git a/packages/graph/lib/commands/EXPLAIN.ts b/packages/graph/lib/commands/EXPLAIN.ts index 99a73bf04b..c690450a10 100644 --- a/packages/graph/lib/commands/EXPLAIN.ts +++ b/packages/graph/lib/commands/EXPLAIN.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, query: RedisArgument) { - return ['GRAPH.EXPLAIN', key, query]; + parseCommand(parser: CommandParser, key: RedisArgument, query: RedisArgument) { + parser.push('GRAPH.EXPLAIN'); + parser.pushKey(key); + parser.push(query); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/LIST.spec.ts b/packages/graph/lib/commands/LIST.spec.ts index 36745efc47..19f18a0e30 100644 --- a/packages/graph/lib/commands/LIST.spec.ts +++ b/packages/graph/lib/commands/LIST.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import LIST from './LIST'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.LIST', () => { it('transformArguments', () => { assert.deepEqual( - LIST.transformArguments(), + parseArgs(LIST), ['GRAPH.LIST'] ); }); diff --git a/packages/graph/lib/commands/LIST.ts b/packages/graph/lib/commands/LIST.ts index 01a868854b..4fe66d748f 100644 --- a/packages/graph/lib/commands/LIST.ts +++ b/packages/graph/lib/commands/LIST.ts @@ -1,10 +1,11 @@ -import { ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['GRAPH.LIST']; + parseCommand(parser: CommandParser) { + parser.push('GRAPH.LIST'); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/PROFILE.spec.ts b/packages/graph/lib/commands/PROFILE.spec.ts index a758365d56..7f16fd3ba5 100644 --- a/packages/graph/lib/commands/PROFILE.spec.ts +++ b/packages/graph/lib/commands/PROFILE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PROFILE from './PROFILE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.PROFILE', () => { it('transformArguments', () => { assert.deepEqual( - PROFILE.transformArguments('key', 'RETURN 0'), + parseArgs(PROFILE, 'key', 'RETURN 0'), ['GRAPH.PROFILE', 'key', 'RETURN 0'] ); }); diff --git a/packages/graph/lib/commands/PROFILE.ts b/packages/graph/lib/commands/PROFILE.ts index 2aa1e83dfb..fba0973baa 100644 --- a/packages/graph/lib/commands/PROFILE.ts +++ b/packages/graph/lib/commands/PROFILE.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, query: RedisArgument) { - return ['GRAPH.PROFILE', key, query]; + parseCommand(parser: CommandParser, key: RedisArgument, query: RedisArgument) { + parser.push('GRAPH.PROFILE'); + parser.pushKey(key); + parser.push(query); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/QUERY.spec.ts b/packages/graph/lib/commands/QUERY.spec.ts index 62c9bcaaef..28c2189645 100644 --- a/packages/graph/lib/commands/QUERY.spec.ts +++ b/packages/graph/lib/commands/QUERY.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import QUERY from './QUERY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.QUERY', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - QUERY.transformArguments('key', 'query'), + parseArgs(QUERY, 'key', 'query'), ['GRAPH.QUERY', 'key', 'query'] ); }); @@ -14,7 +15,7 @@ describe('GRAPH.QUERY', () => { describe('params', () => { it('all types', () => { assert.deepEqual( - QUERY.transformArguments('key', 'query', { + parseArgs(QUERY, 'key', 'query', { params: { null: null, string: '"\\', @@ -30,7 +31,7 @@ describe('GRAPH.QUERY', () => { it('TypeError', () => { assert.throws(() => { - QUERY.transformArguments('key', 'query', { + parseArgs(QUERY, 'key', 'query', { params: { a: Symbol() } @@ -41,7 +42,7 @@ describe('GRAPH.QUERY', () => { it('TIMEOUT', () => { assert.deepEqual( - QUERY.transformArguments('key', 'query', { + parseArgs(QUERY, 'key', 'query', { TIMEOUT: 1 }), ['GRAPH.QUERY', 'key', 'query', 'TIMEOUT', '1'] @@ -50,7 +51,7 @@ describe('GRAPH.QUERY', () => { it('compact', () => { assert.deepEqual( - QUERY.transformArguments('key', 'query', undefined, true), + parseArgs(QUERY, 'key', 'query', undefined, true), ['GRAPH.QUERY', 'key', 'query', '--compact'] ); }); diff --git a/packages/graph/lib/commands/QUERY.ts b/packages/graph/lib/commands/QUERY.ts index 8a05235461..c96c00ff32 100644 --- a/packages/graph/lib/commands/QUERY.ts +++ b/packages/graph/lib/commands/QUERY.ts @@ -1,4 +1,5 @@ -import { RedisArgument, ArrayReply, BlobStringReply, NumberReply, NullReply, TuplesReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, ArrayReply, BlobStringReply, NumberReply, NullReply, TuplesReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; type Headers = ArrayReply; @@ -25,30 +26,28 @@ export interface QueryOptions { TIMEOUT?: number; } -export function transformQueryArguments( +export function parseQueryArguments( command: RedisArgument, + parser: CommandParser, graph: RedisArgument, query: RedisArgument, options?: QueryOptions, compact?: boolean ) { - const args = [ - command, - graph, - options?.params ? - `CYPHER ${queryParamsToString(options.params)} ${query}` : - query - ]; + parser.push(command); + parser.pushKey(graph); + const param = options?.params ? + `CYPHER ${queryParamsToString(options.params)} ${query}` : + query; + parser.push(param); if (options?.TIMEOUT !== undefined) { - args.push('TIMEOUT', options.TIMEOUT.toString()); + parser.push('TIMEOUT', options.TIMEOUT.toString()); } if (compact) { - args.push('--compact'); + parser.push('--compact'); } - - return args; } function queryParamsToString(params: QueryParams) { @@ -85,9 +84,8 @@ function queryParamToString(param: QueryParam): string { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments: transformQueryArguments.bind(undefined, 'GRAPH.QUERY'), + parseCommand: parseQueryArguments.bind(undefined, 'GRAPH.QUERY'), transformReply(reply: UnwrapReply) { return reply.length === 1 ? { headers: undefined, diff --git a/packages/graph/lib/commands/RO_QUERY.spec.ts b/packages/graph/lib/commands/RO_QUERY.spec.ts index 1382954355..fa9459cf64 100644 --- a/packages/graph/lib/commands/RO_QUERY.spec.ts +++ b/packages/graph/lib/commands/RO_QUERY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RO_QUERY from './RO_QUERY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.RO_QUERY', () => { it('transformArguments', () => { assert.deepEqual( - RO_QUERY.transformArguments('key', 'query'), + parseArgs(RO_QUERY, 'key', 'query'), ['GRAPH.RO_QUERY', 'key', 'query'] ); }); diff --git a/packages/graph/lib/commands/RO_QUERY.ts b/packages/graph/lib/commands/RO_QUERY.ts index 5987f511b7..98668675d2 100644 --- a/packages/graph/lib/commands/RO_QUERY.ts +++ b/packages/graph/lib/commands/RO_QUERY.ts @@ -1,9 +1,8 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; -import QUERY, { transformQueryArguments } from './QUERY'; +import { Command } from '@redis/client/lib/RESP/types'; +import QUERY, { parseQueryArguments } from './QUERY'; export default { - FIRST_KEY_INDEX: QUERY.FIRST_KEY_INDEX, IS_READ_ONLY: true, - transformArguments: transformQueryArguments.bind(undefined, 'GRAPH.RO_QUERY'), + parseCommand: parseQueryArguments.bind(undefined, 'GRAPH.RO_QUERY'), transformReply: QUERY.transformReply } as const satisfies Command; diff --git a/packages/graph/lib/commands/SLOWLOG.spec.ts b/packages/graph/lib/commands/SLOWLOG.spec.ts index c1c77286a2..b991d6e7b9 100644 --- a/packages/graph/lib/commands/SLOWLOG.spec.ts +++ b/packages/graph/lib/commands/SLOWLOG.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SLOWLOG from './SLOWLOG'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('GRAPH.SLOWLOG', () => { it('transformArguments', () => { assert.deepEqual( - SLOWLOG.transformArguments('key'), + parseArgs(SLOWLOG, 'key'), ['GRAPH.SLOWLOG', 'key'] ); }); diff --git a/packages/graph/lib/commands/SLOWLOG.ts b/packages/graph/lib/commands/SLOWLOG.ts index 52927f6040..bba615efb2 100644 --- a/packages/graph/lib/commands/SLOWLOG.ts +++ b/packages/graph/lib/commands/SLOWLOG.ts @@ -1,4 +1,5 @@ -import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; type SlowLogRawReply = ArrayReply>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['GRAPH.SLOWLOG', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('GRAPH.SLOWLOG'); + parser.pushKey(key); }, transformReply(reply: UnwrapReply) { return reply.map(log => { diff --git a/packages/graph/lib/commands/index.ts b/packages/graph/lib/commands/index.ts index e93356aa95..362d98f970 100644 --- a/packages/graph/lib/commands/index.ts +++ b/packages/graph/lib/commands/index.ts @@ -1,4 +1,4 @@ -import type { RedisCommands } from '@redis/client/dist/lib/RESP/types'; +import type { RedisCommands } from '@redis/client/lib/RESP/types'; import CONFIG_GET from './CONFIG_GET'; import CONFIG_SET from './CONFIG_SET';; import DELETE from './DELETE'; diff --git a/packages/graph/lib/graph.ts b/packages/graph/lib/graph.ts index 348c8b7155..cacdcd5aec 100644 --- a/packages/graph/lib/graph.ts +++ b/packages/graph/lib/graph.ts @@ -1,5 +1,5 @@ import { RedisClientType } from '@redis/client'; -import { RedisArgument, RedisFunctions, RedisScripts } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, RedisFunctions, RedisScripts } from '@redis/client/lib/RESP/types'; import QUERY, { QueryOptions } from './commands/QUERY'; interface GraphMetadata { diff --git a/packages/json/lib/commands/ARRAPPEND.spec.ts b/packages/json/lib/commands/ARRAPPEND.spec.ts index 3bdd967e23..b2c22e0b9c 100644 --- a/packages/json/lib/commands/ARRAPPEND.spec.ts +++ b/packages/json/lib/commands/ARRAPPEND.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRAPPEND from './ARRAPPEND'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRAPPEND', () => { describe('transformArguments', () => { it('single element', () => { assert.deepEqual( - ARRAPPEND.transformArguments('key', '$', 'value'), + parseArgs(ARRAPPEND, 'key', '$', 'value'), ['JSON.ARRAPPEND', 'key', '$', '"value"'] ); }); it('multiple elements', () => { assert.deepEqual( - ARRAPPEND.transformArguments('key', '$', 1, 2), + parseArgs(ARRAPPEND, 'key', '$', 1, 2), ['JSON.ARRAPPEND', 'key', '$', '1', '2'] ); }); diff --git a/packages/json/lib/commands/ARRAPPEND.ts b/packages/json/lib/commands/ARRAPPEND.ts index 6f486a301d..ee79119b9f 100644 --- a/packages/json/lib/commands/ARRAPPEND.ts +++ b/packages/json/lib/commands/ARRAPPEND.ts @@ -1,27 +1,23 @@ +import { CommandParser } from '@redis/client/lib/client/parser'; import { RedisJSON, transformRedisJsonArgument } from '.'; -import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, path: RedisArgument, json: RedisJSON, ...jsons: Array ) { - const args = new Array(4 + jsons.length); - args[0] = 'JSON.ARRAPPEND'; - args[1] = key; - args[2] = path; - args[3] = transformRedisJsonArgument(json); + parser.push('JSON.ARRAPPEND'); + parser.pushKey(key); + parser.push(path, transformRedisJsonArgument(json)); - let argsIndex = 4; for (let i = 0; i < jsons.length; i++) { - args[argsIndex++] = transformRedisJsonArgument(jsons[i]); + parser.push(transformRedisJsonArgument(jsons[i])); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/ARRINDEX.spec.ts b/packages/json/lib/commands/ARRINDEX.spec.ts index cb946b6251..3c1377354f 100644 --- a/packages/json/lib/commands/ARRINDEX.spec.ts +++ b/packages/json/lib/commands/ARRINDEX.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRINDEX from './ARRINDEX'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRINDEX', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ARRINDEX.transformArguments('key', '$', 'value'), + parseArgs(ARRINDEX, 'key', '$', 'value'), ['JSON.ARRINDEX', 'key', '$', '"value"'] ); }); @@ -14,7 +15,7 @@ describe('JSON.ARRINDEX', () => { describe('with range', () => { it('start only', () => { assert.deepEqual( - ARRINDEX.transformArguments('key', '$', 'value', { + parseArgs(ARRINDEX, 'key', '$', 'value', { range: { start: 0 } @@ -25,7 +26,7 @@ describe('JSON.ARRINDEX', () => { it('with start and stop', () => { assert.deepEqual( - ARRINDEX.transformArguments('key', '$', 'value', { + parseArgs(ARRINDEX, 'key', '$', 'value', { range: { start: 0, stop: 1 diff --git a/packages/json/lib/commands/ARRINDEX.ts b/packages/json/lib/commands/ARRINDEX.ts index 77c54b9252..d0533862c6 100644 --- a/packages/json/lib/commands/ARRINDEX.ts +++ b/packages/json/lib/commands/ARRINDEX.ts @@ -1,4 +1,5 @@ -import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/lib/RESP/types'; import { RedisJSON, transformRedisJsonArgument } from '.'; export interface JsonArrIndexOptions { @@ -9,25 +10,25 @@ export interface JsonArrIndexOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, path: RedisArgument, json: RedisJSON, options?: JsonArrIndexOptions ) { - const args = ['JSON.ARRINDEX', key, path, transformRedisJsonArgument(json)]; + parser.push('JSON.ARRINDEX'); + parser.pushKey(key); + parser.push(path, transformRedisJsonArgument(json)); if (options?.range) { - args.push(options.range.start.toString()); + parser.push(options.range.start.toString()); if (options.range.stop !== undefined) { - args.push(options.range.stop.toString()); + parser.push(options.range.stop.toString()); } } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/ARRINSERT.spec.ts b/packages/json/lib/commands/ARRINSERT.spec.ts index efa824b373..bf9c8a2a05 100644 --- a/packages/json/lib/commands/ARRINSERT.spec.ts +++ b/packages/json/lib/commands/ARRINSERT.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRINSERT from './ARRINSERT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRINSERT', () => { describe('transformArguments', () => { it('single element', () => { assert.deepEqual( - ARRINSERT.transformArguments('key', '$', 0, 'value'), + parseArgs(ARRINSERT, 'key', '$', 0, 'value'), ['JSON.ARRINSERT', 'key', '$', '0', '"value"'] ); }); it('multiple elements', () => { assert.deepEqual( - ARRINSERT.transformArguments('key', '$', 0, '1', '2'), + parseArgs(ARRINSERT, 'key', '$', 0, '1', '2'), ['JSON.ARRINSERT', 'key', '$', '0', '"1"', '"2"'] ); }); diff --git a/packages/json/lib/commands/ARRINSERT.ts b/packages/json/lib/commands/ARRINSERT.ts index c089188472..7a55577c9d 100644 --- a/packages/json/lib/commands/ARRINSERT.ts +++ b/packages/json/lib/commands/ARRINSERT.ts @@ -1,29 +1,24 @@ -import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/lib/RESP/types'; import { RedisJSON, transformRedisJsonArgument } from '.'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, path: RedisArgument, index: number, json: RedisJSON, ...jsons: Array ) { - const args = new Array(4 + jsons.length); - args[0] = 'JSON.ARRINSERT'; - args[1] = key; - args[2] = path; - args[3] = index.toString(); - args[4] = transformRedisJsonArgument(json); + parser.push('JSON.ARRINSERT'); + parser.pushKey(key); + parser.push(path, index.toString(), transformRedisJsonArgument(json)); - let argsIndex = 5; for (let i = 0; i < jsons.length; i++) { - args[argsIndex++] = transformRedisJsonArgument(jsons[i]); + parser.push(transformRedisJsonArgument(jsons[i])); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/ARRLEN.spec.ts b/packages/json/lib/commands/ARRLEN.spec.ts index 5ecb01b2ce..dcf7d35acb 100644 --- a/packages/json/lib/commands/ARRLEN.spec.ts +++ b/packages/json/lib/commands/ARRLEN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRLEN from './ARRLEN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRLEN', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ARRLEN.transformArguments('key'), + parseArgs(ARRLEN, 'key'), ['JSON.ARRLEN', 'key'] ); }); it('with path', () => { assert.deepEqual( - ARRLEN.transformArguments('key', { + parseArgs(ARRLEN, 'key', { path: '$' }), ['JSON.ARRLEN', 'key', '$'] diff --git a/packages/json/lib/commands/ARRLEN.ts b/packages/json/lib/commands/ARRLEN.ts index d30032c7d8..26accf8df9 100644 --- a/packages/json/lib/commands/ARRLEN.ts +++ b/packages/json/lib/commands/ARRLEN.ts @@ -1,20 +1,18 @@ -import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonArrLenOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: JsonArrLenOptions) { - const args = ['JSON.ARRLEN', key]; - + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonArrLenOptions) { + parser.push('JSON.ARRLEN'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/ARRPOP.spec.ts b/packages/json/lib/commands/ARRPOP.spec.ts index 1b069ba392..f823e7fc08 100644 --- a/packages/json/lib/commands/ARRPOP.spec.ts +++ b/packages/json/lib/commands/ARRPOP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRPOP from './ARRPOP'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRPOP', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - ARRPOP.transformArguments('key'), + parseArgs(ARRPOP, 'key'), ['JSON.ARRPOP', 'key'] ); }); it('with path', () => { assert.deepEqual( - ARRPOP.transformArguments('key', { + parseArgs(ARRPOP, 'key', { path: '$' }), ['JSON.ARRPOP', 'key', '$'] @@ -22,7 +23,7 @@ describe('JSON.ARRPOP', () => { it('with path and index', () => { assert.deepEqual( - ARRPOP.transformArguments('key', { + parseArgs(ARRPOP, 'key', { path: '$', index: 0 }), diff --git a/packages/json/lib/commands/ARRPOP.ts b/packages/json/lib/commands/ARRPOP.ts index 4eafe9fdde..375668471d 100644 --- a/packages/json/lib/commands/ARRPOP.ts +++ b/packages/json/lib/commands/ARRPOP.ts @@ -1,5 +1,6 @@ -import { RedisArgument, ArrayReply, NullReply, BlobStringReply, Command, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; -import { isArrayReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NullReply, BlobStringReply, Command, UnwrapReply } from '@redis/client/lib/RESP/types'; +import { isArrayReply } from '@redis/client/lib/commands/generic-transformers'; import { transformRedisJsonNullReply } from '.'; export interface RedisArrPopOptions { @@ -8,20 +9,18 @@ export interface RedisArrPopOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: RedisArrPopOptions) { - const args = ['JSON.ARRPOP', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: RedisArrPopOptions) { + parser.push('JSON.ARRPOP'); + parser.pushKey(key); if (options) { - args.push(options.path); + parser.push(options.path); if (options.index !== undefined) { - args.push(options.index.toString()); + parser.push(options.index.toString()); } } - - return args; }, transformReply(reply: NullReply | BlobStringReply | ArrayReply) { return isArrayReply(reply) ? diff --git a/packages/json/lib/commands/ARRTRIM.spec.ts b/packages/json/lib/commands/ARRTRIM.spec.ts index 4c2f72aaa5..e346716e8d 100644 --- a/packages/json/lib/commands/ARRTRIM.spec.ts +++ b/packages/json/lib/commands/ARRTRIM.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ARRTRIM from './ARRTRIM'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.ARRTRIM', () => { it('transformArguments', () => { assert.deepEqual( - ARRTRIM.transformArguments('key', '$', 0, 1), + parseArgs(ARRTRIM, 'key', '$', 0, 1), ['JSON.ARRTRIM', 'key', '$', '0', '1'] ); }); diff --git a/packages/json/lib/commands/ARRTRIM.ts b/packages/json/lib/commands/ARRTRIM.ts index ab31f15949..e7cde0dc17 100644 --- a/packages/json/lib/commands/ARRTRIM.ts +++ b/packages/json/lib/commands/ARRTRIM.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, path: RedisArgument, start: number, stop: number) { - return ['JSON.ARRTRIM', key, path, start.toString(), stop.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, path: RedisArgument, start: number, stop: number) { + parser.push('JSON.ARRTRIM'); + parser.pushKey(key); + parser.push(path, start.toString(), stop.toString()); }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/CLEAR.spec.ts b/packages/json/lib/commands/CLEAR.spec.ts index 983e6bec2d..c1786cc1dd 100644 --- a/packages/json/lib/commands/CLEAR.spec.ts +++ b/packages/json/lib/commands/CLEAR.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CLEAR from './CLEAR'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.CLEAR', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CLEAR.transformArguments('key'), + parseArgs(CLEAR, 'key'), ['JSON.CLEAR', 'key'] ); }); it('with path', () => { assert.deepEqual( - CLEAR.transformArguments('key', { + parseArgs(CLEAR, 'key', { path: '$' }), ['JSON.CLEAR', 'key', '$'] diff --git a/packages/json/lib/commands/CLEAR.ts b/packages/json/lib/commands/CLEAR.ts index 23e86d900e..65d69ef18e 100644 --- a/packages/json/lib/commands/CLEAR.ts +++ b/packages/json/lib/commands/CLEAR.ts @@ -1,20 +1,19 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonClearOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonClearOptions) { - const args = ['JSON.CLEAR', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonClearOptions) { + parser.push('JSON.CLEAR'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/json/lib/commands/DEBUG_MEMORY.spec.ts b/packages/json/lib/commands/DEBUG_MEMORY.spec.ts index c41d07cb27..09c29328d8 100644 --- a/packages/json/lib/commands/DEBUG_MEMORY.spec.ts +++ b/packages/json/lib/commands/DEBUG_MEMORY.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DEBUG_MEMORY from './DEBUG_MEMORY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.DEBUG MEMORY', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - DEBUG_MEMORY.transformArguments('key'), + parseArgs(DEBUG_MEMORY, 'key'), ['JSON.DEBUG', 'MEMORY', 'key'] ); }); it('with path', () => { assert.deepEqual( - DEBUG_MEMORY.transformArguments('key', { + parseArgs(DEBUG_MEMORY, 'key', { path: '$' }), ['JSON.DEBUG', 'MEMORY', 'key', '$'] diff --git a/packages/json/lib/commands/DEBUG_MEMORY.ts b/packages/json/lib/commands/DEBUG_MEMORY.ts index c2e730b9dc..5c4641c327 100644 --- a/packages/json/lib/commands/DEBUG_MEMORY.ts +++ b/packages/json/lib/commands/DEBUG_MEMORY.ts @@ -1,20 +1,19 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonDebugMemoryOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 2, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonDebugMemoryOptions) { - const args = ['JSON.DEBUG', 'MEMORY', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonDebugMemoryOptions) { + parser.push('JSON.DEBUG', 'MEMORY'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/json/lib/commands/DEL.spec.ts b/packages/json/lib/commands/DEL.spec.ts index 18f6a8f2db..a008c3b9b2 100644 --- a/packages/json/lib/commands/DEL.spec.ts +++ b/packages/json/lib/commands/DEL.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DEL from './DEL'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.DEL', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - DEL.transformArguments('key'), + parseArgs(DEL, 'key'), ['JSON.DEL', 'key'] ); }); it('with path', () => { assert.deepEqual( - DEL.transformArguments('key', { + parseArgs(DEL, 'key', { path: '$.path' }), ['JSON.DEL', 'key', '$.path'] diff --git a/packages/json/lib/commands/DEL.ts b/packages/json/lib/commands/DEL.ts index f6952a8dc6..d4d8ed4620 100644 --- a/packages/json/lib/commands/DEL.ts +++ b/packages/json/lib/commands/DEL.ts @@ -1,20 +1,19 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonDelOptions { path?: RedisArgument } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonDelOptions) { - const args = ['JSON.DEL', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonDelOptions) { + parser.push('JSON.DEL'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/json/lib/commands/FORGET.spec.ts b/packages/json/lib/commands/FORGET.spec.ts index 04066ec43a..888fff5659 100644 --- a/packages/json/lib/commands/FORGET.spec.ts +++ b/packages/json/lib/commands/FORGET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import FORGET from './FORGET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.FORGET', () => { describe('transformArguments', () => { it('key', () => { assert.deepEqual( - FORGET.transformArguments('key'), + parseArgs(FORGET, 'key'), ['JSON.FORGET', 'key'] ); }); it('key, path', () => { assert.deepEqual( - FORGET.transformArguments('key', { + parseArgs(FORGET, 'key', { path: '$.path' }), ['JSON.FORGET', 'key', '$.path'] diff --git a/packages/json/lib/commands/FORGET.ts b/packages/json/lib/commands/FORGET.ts index 68335ee92e..1b5b97038e 100644 --- a/packages/json/lib/commands/FORGET.ts +++ b/packages/json/lib/commands/FORGET.ts @@ -1,20 +1,19 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonForgetOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonForgetOptions) { - const args = ['JSON.FORGET', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonForgetOptions) { + parser.push('JSON.FORGET'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/json/lib/commands/GET.spec.ts b/packages/json/lib/commands/GET.spec.ts index 6d6ff14f67..0741de316e 100644 --- a/packages/json/lib/commands/GET.spec.ts +++ b/packages/json/lib/commands/GET.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GET from './GET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.GET', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - GET.transformArguments('key'), + parseArgs(GET, 'key'), ['JSON.GET', 'key'] ); }); @@ -14,14 +15,14 @@ describe('JSON.GET', () => { describe('with path', () => { it('string', () => { assert.deepEqual( - GET.transformArguments('key', { path: '$' }), + parseArgs(GET, 'key', { path: '$' }), ['JSON.GET', 'key', '$'] ); }); it('array', () => { assert.deepEqual( - GET.transformArguments('key', { path: ['$.1', '$.2'] }), + parseArgs(GET, 'key', { path: ['$.1', '$.2'] }), ['JSON.GET', 'key', '$.1', '$.2'] ); }); diff --git a/packages/json/lib/commands/GET.ts b/packages/json/lib/commands/GET.ts index b7bcc52e3c..3d623483d2 100644 --- a/packages/json/lib/commands/GET.ts +++ b/packages/json/lib/commands/GET.ts @@ -1,5 +1,6 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { transformRedisJsonNullReply } from '.'; export interface JsonGetOptions { @@ -7,16 +8,13 @@ export interface JsonGetOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonGetOptions) { - let args = ['JSON.GET', key]; - + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonGetOptions) { + parser.push('JSON.GET'); + parser.pushKey(key); if (options?.path !== undefined) { - args = pushVariadicArguments(args, options.path); + parser.pushVariadic(options.path) } - - return args; }, transformReply: transformRedisJsonNullReply } as const satisfies Command; diff --git a/packages/json/lib/commands/MERGE.spec.ts b/packages/json/lib/commands/MERGE.spec.ts index 56f5d25e7d..30a092035c 100644 --- a/packages/json/lib/commands/MERGE.spec.ts +++ b/packages/json/lib/commands/MERGE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MERGE from './MERGE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.MERGE', () => { it('transformArguments', () => { assert.deepEqual( - MERGE.transformArguments('key', '$', 'value'), + parseArgs(MERGE, 'key', '$', 'value'), ['JSON.MERGE', 'key', '$', '"value"'] ); }); diff --git a/packages/json/lib/commands/MERGE.ts b/packages/json/lib/commands/MERGE.ts index 90cd080a06..25ae84c6ed 100644 --- a/packages/json/lib/commands/MERGE.ts +++ b/packages/json/lib/commands/MERGE.ts @@ -1,16 +1,13 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; import { RedisJSON, transformRedisJsonArgument } from '.'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, path: RedisArgument, value: RedisJSON) { - return [ - 'JSON.MERGE', - key, - path, - transformRedisJsonArgument(value) - ]; + parseCommand(parser: CommandParser, key: RedisArgument, path: RedisArgument, value: RedisJSON) { + parser.push('JSON.MERGE'); + parser.pushKey(key); + parser.push(path, transformRedisJsonArgument(value)); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/json/lib/commands/MGET.spec.ts b/packages/json/lib/commands/MGET.spec.ts index 1bfaecd6da..2d8efafde7 100644 --- a/packages/json/lib/commands/MGET.spec.ts +++ b/packages/json/lib/commands/MGET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MGET from './MGET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.MGET', () => { it('transformArguments', () => { assert.deepEqual( - MGET.transformArguments(['1', '2'], '$'), + parseArgs(MGET, ['1', '2'], '$'), ['JSON.MGET', '1', '2', '$'] ); }); diff --git a/packages/json/lib/commands/MGET.ts b/packages/json/lib/commands/MGET.ts index a7aea82ac2..79241bee7c 100644 --- a/packages/json/lib/commands/MGET.ts +++ b/packages/json/lib/commands/MGET.ts @@ -1,15 +1,13 @@ -import { RedisArgument, UnwrapReply, ArrayReply, NullReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, UnwrapReply, ArrayReply, NullReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; import { transformRedisJsonNullReply } from '.'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(keys: Array, path: RedisArgument) { - return [ - 'JSON.MGET', - ...keys, - path - ]; + parseCommand(parser: CommandParser, keys: Array, path: RedisArgument) { + parser.push('JSON.MGET'); + parser.pushKeys(keys); + parser.push(path); }, transformReply(reply: UnwrapReply>) { return reply.map(json => transformRedisJsonNullReply(json)) diff --git a/packages/json/lib/commands/MSET.spec.ts b/packages/json/lib/commands/MSET.spec.ts index 360890234c..38e8b077e8 100644 --- a/packages/json/lib/commands/MSET.spec.ts +++ b/packages/json/lib/commands/MSET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MSET from './MSET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.MSET', () => { it('transformArguments', () => { assert.deepEqual( - MSET.transformArguments([{ + parseArgs(MSET, [{ key: '1', path: '$', value: 1 diff --git a/packages/json/lib/commands/MSET.ts b/packages/json/lib/commands/MSET.ts index a081bfd543..b6b42563c7 100644 --- a/packages/json/lib/commands/MSET.ts +++ b/packages/json/lib/commands/MSET.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; import { RedisJSON, transformRedisJsonArgument } from '.'; export interface JsonMSetItem { @@ -8,21 +9,14 @@ export interface JsonMSetItem { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(items: Array) { - const args = new Array(1 + items.length * 3); - args[0] = 'JSON.MSET'; + parseCommand(parser: CommandParser, items: Array) { + parser.push('JSON.MSET'); - let argsIndex = 1; for (let i = 0; i < items.length; i++) { - const item = items[i]; - args[argsIndex++] = item.key; - args[argsIndex++] = item.path; - args[argsIndex++] = transformRedisJsonArgument(item.value); + parser.pushKey(items[i].key); + parser.push(items[i].path, transformRedisJsonArgument(items[i].value)); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/json/lib/commands/NUMINCRBY.spec.ts b/packages/json/lib/commands/NUMINCRBY.spec.ts index d0bffd2bd2..b438069e80 100644 --- a/packages/json/lib/commands/NUMINCRBY.spec.ts +++ b/packages/json/lib/commands/NUMINCRBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import NUMINCRBY from './NUMINCRBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.NUMINCRBY', () => { it('transformArguments', () => { assert.deepEqual( - NUMINCRBY.transformArguments('key', '$', 1), + parseArgs(NUMINCRBY, 'key', '$', 1), ['JSON.NUMINCRBY', 'key', '$', '1'] ); }); diff --git a/packages/json/lib/commands/NUMINCRBY.ts b/packages/json/lib/commands/NUMINCRBY.ts index 65cc7db68a..8c41194a9b 100644 --- a/packages/json/lib/commands/NUMINCRBY.ts +++ b/packages/json/lib/commands/NUMINCRBY.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, NumberReply, DoubleReply, NullReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, DoubleReply, NullReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, path: RedisArgument, by: number) { - return ['JSON.NUMINCRBY', key, path, by.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, path: RedisArgument, by: number) { + parser.push('JSON.NUMINCRBY'); + parser.pushKey(key); + parser.push(path, by.toString()); }, transformReply: { 2: (reply: UnwrapReply) => { diff --git a/packages/json/lib/commands/NUMMULTBY.spec.ts b/packages/json/lib/commands/NUMMULTBY.spec.ts index 9767c2b097..24ee932e95 100644 --- a/packages/json/lib/commands/NUMMULTBY.spec.ts +++ b/packages/json/lib/commands/NUMMULTBY.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import NUMMULTBY from './NUMMULTBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.NUMMULTBY', () => { it('transformArguments', () => { assert.deepEqual( - NUMMULTBY.transformArguments('key', '$', 2), + parseArgs(NUMMULTBY, 'key', '$', 2), ['JSON.NUMMULTBY', 'key', '$', '2'] ); }); diff --git a/packages/json/lib/commands/NUMMULTBY.ts b/packages/json/lib/commands/NUMMULTBY.ts index 255685a9a5..5eeb4b50e8 100644 --- a/packages/json/lib/commands/NUMMULTBY.ts +++ b/packages/json/lib/commands/NUMMULTBY.ts @@ -1,11 +1,13 @@ -import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; import NUMINCRBY from './NUMINCRBY'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, path: RedisArgument, by: number) { - return ['JSON.NUMMULTBY', key, path, by.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, path: RedisArgument, by: number) { + parser.push('JSON.NUMMULTBY'); + parser.pushKey(key); + parser.push(path, by.toString()); }, transformReply: NUMINCRBY.transformReply } as const satisfies Command; diff --git a/packages/json/lib/commands/OBJKEYS.spec.ts b/packages/json/lib/commands/OBJKEYS.spec.ts index dc984cb2ce..0d2176248e 100644 --- a/packages/json/lib/commands/OBJKEYS.spec.ts +++ b/packages/json/lib/commands/OBJKEYS.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJKEYS from './OBJKEYS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.OBJKEYS', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - OBJKEYS.transformArguments('key'), + parseArgs(OBJKEYS, 'key'), ['JSON.OBJKEYS', 'key'] ); }); it('with path', () => { assert.deepEqual( - OBJKEYS.transformArguments('key', { + parseArgs(OBJKEYS, 'key', { path: '$' }), ['JSON.OBJKEYS', 'key', '$'] diff --git a/packages/json/lib/commands/OBJKEYS.ts b/packages/json/lib/commands/OBJKEYS.ts index fb8ae6bb03..6d23da2053 100644 --- a/packages/json/lib/commands/OBJKEYS.ts +++ b/packages/json/lib/commands/OBJKEYS.ts @@ -1,20 +1,18 @@ -import { RedisArgument, ArrayReply, BlobStringReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonObjKeysOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: JsonObjKeysOptions) { - const args = ['JSON.OBJKEYS', key]; - + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonObjKeysOptions) { + parser.push('JSON.OBJKEYS'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply | ArrayReply | NullReply> } as const satisfies Command; diff --git a/packages/json/lib/commands/OBJLEN.spec.ts b/packages/json/lib/commands/OBJLEN.spec.ts index 8f616107fd..a5664a4d6b 100644 --- a/packages/json/lib/commands/OBJLEN.spec.ts +++ b/packages/json/lib/commands/OBJLEN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import OBJLEN from './OBJLEN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.OBJLEN', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - OBJLEN.transformArguments('key'), + parseArgs(OBJLEN, 'key'), ['JSON.OBJLEN', 'key'] ); }); it('with path', () => { assert.deepEqual( - OBJLEN.transformArguments('key', { + parseArgs(OBJLEN, 'key', { path: '$' }), ['JSON.OBJLEN', 'key', '$'] diff --git a/packages/json/lib/commands/OBJLEN.ts b/packages/json/lib/commands/OBJLEN.ts index f9c45e336a..e15a72e216 100644 --- a/packages/json/lib/commands/OBJLEN.ts +++ b/packages/json/lib/commands/OBJLEN.ts @@ -1,20 +1,18 @@ -import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, ArrayReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonObjLenOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: JsonObjLenOptions) { - const args = ['JSON.OBJLEN', key]; - + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonObjLenOptions) { + parser.push('JSON.OBJLEN'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/RESP.spec.ts b/packages/json/lib/commands/RESP.spec.ts index 6dfc336032..2cb3e9e15c 100644 --- a/packages/json/lib/commands/RESP.spec.ts +++ b/packages/json/lib/commands/RESP.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './RESP'; +import RESP from './RESP'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('RESP', () => { describe('transformArguments', () => { it('without path', () => { assert.deepEqual( - transformArguments('key'), + parseArgs(RESP, 'key'), ['JSON.RESP', 'key'] ); }); it('with path', () => { assert.deepEqual( - transformArguments('key', '$'), + parseArgs(RESP, 'key', '$'), ['JSON.RESP', 'key', '$'] ); }); diff --git a/packages/json/lib/commands/RESP.ts b/packages/json/lib/commands/RESP.ts index fcf54cd353..c971383395 100644 --- a/packages/json/lib/commands/RESP.ts +++ b/packages/json/lib/commands/RESP.ts @@ -1,15 +1,16 @@ -export const FIRST_KEY_INDEX = 1; - -export function transformArguments(key: string, path?: string): Array { - const args = ['JSON.RESP', key]; - - if (path) { - args.push(path); - } - - return args; -} +import { CommandParser } from "@redis/client/lib/client/parser"; +import { Command, RedisArgument } from "@redis/client/lib/RESP/types"; type RESPReply = Array; -export declare function transformReply(): RESPReply; +export default { + IS_READ_ONLY: true, + parseCommand(parser: CommandParser, key: RedisArgument, path?: string) { + parser.push('JSON.RESP'); + parser.pushKey(key); + if (path !== undefined) { + parser.push(path); + } + }, + transformReply: undefined as unknown as () => RESPReply + } as const satisfies Command; \ No newline at end of file diff --git a/packages/json/lib/commands/SET.spec.ts b/packages/json/lib/commands/SET.spec.ts index 15e2707328..7bd927f08e 100644 --- a/packages/json/lib/commands/SET.spec.ts +++ b/packages/json/lib/commands/SET.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SET from './SET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.SET', () => { describe('transformArguments', () => { it('transformArguments', () => { assert.deepEqual( - SET.transformArguments('key', '$', 'json'), + parseArgs(SET, 'key', '$', 'json'), ['JSON.SET', 'key', '$', '"json"'] ); }); it('NX', () => { assert.deepEqual( - SET.transformArguments('key', '$', 'json', { NX: true }), + parseArgs(SET, 'key', '$', 'json', { NX: true }), ['JSON.SET', 'key', '$', '"json"', 'NX'] ); }); it('XX', () => { assert.deepEqual( - SET.transformArguments('key', '$', 'json', { XX: true }), + parseArgs(SET, 'key', '$', 'json', { XX: true }), ['JSON.SET', 'key', '$', '"json"', 'XX'] ); }); diff --git a/packages/json/lib/commands/SET.ts b/packages/json/lib/commands/SET.ts index 78aea4b354..6bd89803de 100644 --- a/packages/json/lib/commands/SET.ts +++ b/packages/json/lib/commands/SET.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, NullReply, Command } from '@redis/client/lib/RESP/types'; import { RedisJSON, transformRedisJsonArgument } from '.'; export interface JsonSetOptions { @@ -14,25 +15,25 @@ export interface JsonSetOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, path: RedisArgument, json: RedisJSON, options?: JsonSetOptions ) { - const args = ['JSON.SET', key, path, transformRedisJsonArgument(json)]; + parser.push('JSON.SET'); + parser.pushKey(key); + parser.push(path, transformRedisJsonArgument(json)); if (options?.condition) { - args.push(options?.condition); + parser.push(options?.condition); } else if (options?.NX) { - args.push('NX'); + parser.push('NX'); } else if (options?.XX) { - args.push('XX'); + parser.push('XX'); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> | NullReply } as const satisfies Command; diff --git a/packages/json/lib/commands/STRAPPEND.spec.ts b/packages/json/lib/commands/STRAPPEND.spec.ts index 0d8bdb5718..ebd539130e 100644 --- a/packages/json/lib/commands/STRAPPEND.spec.ts +++ b/packages/json/lib/commands/STRAPPEND.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import STRAPPEND from './STRAPPEND'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.STRAPPEND', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - STRAPPEND.transformArguments('key', 'append'), + parseArgs(STRAPPEND, 'key', 'append'), ['JSON.STRAPPEND', 'key', '"append"'] ); }); it('with path', () => { assert.deepEqual( - STRAPPEND.transformArguments('key', 'append', { + parseArgs(STRAPPEND, 'key', 'append', { path: '$' }), ['JSON.STRAPPEND', 'key', '$', '"append"'] diff --git a/packages/json/lib/commands/STRAPPEND.ts b/packages/json/lib/commands/STRAPPEND.ts index 12ee7cc394..97bbebf931 100644 --- a/packages/json/lib/commands/STRAPPEND.ts +++ b/packages/json/lib/commands/STRAPPEND.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, NullReply, NumberReply, ArrayReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, NullReply, NumberReply, ArrayReply } from '@redis/client/lib/RESP/types'; import { transformRedisJsonArgument } from '.'; export interface JsonStrAppendOptions { @@ -6,17 +7,16 @@ export interface JsonStrAppendOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, append: string, options?: JsonStrAppendOptions) { - const args = ['JSON.STRAPPEND', key]; + parseCommand(parser: CommandParser, key: RedisArgument, append: string, options?: JsonStrAppendOptions) { + parser.push('JSON.STRAPPEND'); + parser.pushKey(key); if (options?.path !== undefined) { - args.push(options.path); + parser.push(options.path); } - args.push(transformRedisJsonArgument(append)); - return args; + parser.push(transformRedisJsonArgument(append)); }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/STRLEN.spec.ts b/packages/json/lib/commands/STRLEN.spec.ts index e058e48a63..b6881b5bd5 100644 --- a/packages/json/lib/commands/STRLEN.spec.ts +++ b/packages/json/lib/commands/STRLEN.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import STRLEN from './STRLEN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.STRLEN', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - STRLEN.transformArguments('key'), + parseArgs(STRLEN, 'key'), ['JSON.STRLEN', 'key'] ); }); it('with path', () => { assert.deepEqual( - STRLEN.transformArguments('key', { + parseArgs(STRLEN, 'key', { path: '$' }), ['JSON.STRLEN', 'key', '$'] diff --git a/packages/json/lib/commands/STRLEN.ts b/packages/json/lib/commands/STRLEN.ts index 3b514d9cab..b72f30cd6d 100644 --- a/packages/json/lib/commands/STRLEN.ts +++ b/packages/json/lib/commands/STRLEN.ts @@ -1,20 +1,19 @@ -import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '@redis/client/lib/RESP/types'; export interface JsonStrLenOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: JsonStrLenOptions) { - const args = ['JSON.STRLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonStrLenOptions) { + parser.push('JSON.STRLEN'); + parser.pushKey(key); if (options?.path) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: undefined as unknown as () => NumberReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/TOGGLE.spec.ts b/packages/json/lib/commands/TOGGLE.spec.ts index c8a7887790..173c7708f4 100644 --- a/packages/json/lib/commands/TOGGLE.spec.ts +++ b/packages/json/lib/commands/TOGGLE.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TOGGLE from './TOGGLE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.TOGGLE', () => { it('transformArguments', () => { assert.deepEqual( - TOGGLE.transformArguments('key', '$'), + parseArgs(TOGGLE, 'key', '$'), ['JSON.TOGGLE', 'key', '$'] ); }); diff --git a/packages/json/lib/commands/TOGGLE.ts b/packages/json/lib/commands/TOGGLE.ts index 2a8df3eba3..2707d54b6f 100644 --- a/packages/json/lib/commands/TOGGLE.ts +++ b/packages/json/lib/commands/TOGGLE.ts @@ -1,10 +1,12 @@ -import { RedisArgument, ArrayReply, NumberReply, NullReply, Command, } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, NumberReply, NullReply, Command, } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, path: RedisArgument) { - return ['JSON.TOGGLE', key, path]; + parseCommand(parser: CommandParser, key: RedisArgument, path: RedisArgument) { + parser.push('JSON.TOGGLE'); + parser.pushKey(key); + parser.push(path); }, transformReply: undefined as unknown as () => NumberReply | NullReply | ArrayReply } as const satisfies Command; diff --git a/packages/json/lib/commands/TYPE.spec.ts b/packages/json/lib/commands/TYPE.spec.ts index 103ce59de6..1b6ad10981 100644 --- a/packages/json/lib/commands/TYPE.spec.ts +++ b/packages/json/lib/commands/TYPE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TYPE from './TYPE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('JSON.TYPE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - TYPE.transformArguments('key'), + parseArgs(TYPE, 'key'), ['JSON.TYPE', 'key'] ); }); it('with path', () => { assert.deepEqual( - TYPE.transformArguments('key', { + parseArgs(TYPE, 'key', { path: '$' }), ['JSON.TYPE', 'key', '$'] diff --git a/packages/json/lib/commands/TYPE.ts b/packages/json/lib/commands/TYPE.ts index c2eea9856e..d19de31df6 100644 --- a/packages/json/lib/commands/TYPE.ts +++ b/packages/json/lib/commands/TYPE.ts @@ -1,20 +1,19 @@ -import { NullReply, BlobStringReply, ArrayReply, Command, RedisArgument, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { NullReply, BlobStringReply, ArrayReply, Command, RedisArgument, UnwrapReply } from '@redis/client/lib/RESP/types'; export interface JsonTypeOptions { path?: RedisArgument; } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: JsonTypeOptions) { - const args = ['JSON.TYPE', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: JsonTypeOptions) { + parser.push('JSON.TYPE'); + parser.pushKey(key); if (options?.path) { - args.push(options.path); + parser.push(options.path); } - - return args; }, transformReply: { 2: undefined as unknown as () => NullReply | BlobStringReply | ArrayReply, @@ -24,4 +23,3 @@ export default { } }, } as const satisfies Command; - diff --git a/packages/json/lib/commands/index.ts b/packages/json/lib/commands/index.ts index 2724ff2565..8ea44ce804 100644 --- a/packages/json/lib/commands/index.ts +++ b/packages/json/lib/commands/index.ts @@ -1,4 +1,4 @@ -import { BlobStringReply, NullReply, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; +import { BlobStringReply, NullReply, UnwrapReply } from '@redis/client/lib/RESP/types'; import ARRAPPEND from './ARRAPPEND'; import ARRINDEX from './ARRINDEX'; import ARRINSERT from './ARRINSERT'; @@ -23,7 +23,7 @@ import STRAPPEND from './STRAPPEND'; import STRLEN from './STRLEN'; import TOGGLE from './TOGGLE'; import TYPE from './TYPE'; -import { isNullReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { isNullReply } from '@redis/client/lib/commands/generic-transformers'; export default { ARRAPPEND, diff --git a/packages/search/lib/commands/AGGREGATE.spec.ts b/packages/search/lib/commands/AGGREGATE.spec.ts index 50ef44f2bd..787fbd1472 100644 --- a/packages/search/lib/commands/AGGREGATE.spec.ts +++ b/packages/search/lib/commands/AGGREGATE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import AGGREGATE from './AGGREGATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('AGGREGATE', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*'), + parseArgs(AGGREGATE, 'index', '*'), ['FT.AGGREGATE', 'index', '*'] ); }); it('with VERBATIM', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { VERBATIM: true }), ['FT.AGGREGATE', 'index', '*', 'VERBATIM'] @@ -22,7 +23,7 @@ describe('AGGREGATE', () => { it('with ADDSCORES', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { ADDSCORES: true }), + parseArgs(AGGREGATE, 'index', '*', { ADDSCORES: true }), ['FT.AGGREGATE', 'index', '*', 'ADDSCORES'] ); }); @@ -32,7 +33,7 @@ describe('AGGREGATE', () => { describe('without alias', () => { it('string', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { LOAD: '@property' }), ['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property'] @@ -41,7 +42,7 @@ describe('AGGREGATE', () => { it('{ identifier: string }', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { LOAD: { identifier: '@property' } @@ -53,7 +54,7 @@ describe('AGGREGATE', () => { it('with alias', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { LOAD: { identifier: '@property', AS: 'alias' @@ -66,7 +67,7 @@ describe('AGGREGATE', () => { it('multiple', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { LOAD: ['@1', '@2'] }), ['FT.AGGREGATE', 'index', '*', 'LOAD', '2', '@1', '@2'] @@ -80,7 +81,7 @@ describe('AGGREGATE', () => { describe('without properties', () => { it('without alias', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -94,7 +95,7 @@ describe('AGGREGATE', () => { it('with alias', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -111,7 +112,7 @@ describe('AGGREGATE', () => { describe('with properties', () => { it('single', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', properties: '@property', @@ -126,7 +127,7 @@ describe('AGGREGATE', () => { it('multiple', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', properties: ['@1', '@2'], @@ -143,7 +144,7 @@ describe('AGGREGATE', () => { it('COUNT_DISTINCT', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -158,7 +159,7 @@ describe('AGGREGATE', () => { it('COUNT_DISTINCTISH', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -173,7 +174,7 @@ describe('AGGREGATE', () => { it('SUM', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -188,7 +189,7 @@ describe('AGGREGATE', () => { it('MIN', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -203,7 +204,7 @@ describe('AGGREGATE', () => { it('MAX', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -218,7 +219,7 @@ describe('AGGREGATE', () => { it('AVG', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -230,10 +231,9 @@ describe('AGGREGATE', () => { ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'AVG', '1', '@property'] ); }); - it('STDDEV', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -248,7 +248,7 @@ describe('AGGREGATE', () => { it('QUANTILE', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -264,7 +264,7 @@ describe('AGGREGATE', () => { it('TOLIST', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -280,7 +280,7 @@ describe('AGGREGATE', () => { describe('FIRST_VALUE', () => { it('simple', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -297,7 +297,7 @@ describe('AGGREGATE', () => { describe('without direction', () => { it('string', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -314,7 +314,7 @@ describe('AGGREGATE', () => { it('{ property: string }', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -333,7 +333,7 @@ describe('AGGREGATE', () => { it('with direction', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -354,7 +354,7 @@ describe('AGGREGATE', () => { it('RANDOM_SAMPLE', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'GROUPBY', REDUCE: { @@ -372,7 +372,7 @@ describe('AGGREGATE', () => { describe('SORTBY', () => { it('string', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'SORTBY', BY: '@by' @@ -384,7 +384,7 @@ describe('AGGREGATE', () => { it('Array', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'SORTBY', BY: ['@1', '@2'] @@ -396,7 +396,7 @@ describe('AGGREGATE', () => { it('with MAX', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'SORTBY', BY: '@by', @@ -410,7 +410,7 @@ describe('AGGREGATE', () => { describe('APPLY', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'APPLY', expression: '@field + 1', @@ -423,7 +423,7 @@ describe('AGGREGATE', () => { describe('LIMIT', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'LIMIT', from: 0, @@ -436,7 +436,7 @@ describe('AGGREGATE', () => { describe('FILTER', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { STEPS: [{ type: 'FILTER', expression: '@field != ""' @@ -449,7 +449,7 @@ describe('AGGREGATE', () => { it('with PARAMS', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { PARAMS: { param: 'value' } @@ -460,7 +460,7 @@ describe('AGGREGATE', () => { it('with DIALECT', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { + parseArgs(AGGREGATE, 'index', '*', { DIALECT: 1 }), ['FT.AGGREGATE', 'index', '*', 'DIALECT', '1'] @@ -469,7 +469,7 @@ describe('AGGREGATE', () => { it('with TIMEOUT', () => { assert.deepEqual( - AGGREGATE.transformArguments('index', '*', { TIMEOUT: 10 }), + parseArgs(AGGREGATE, 'index', '*', { TIMEOUT: 10 }), ['FT.AGGREGATE', 'index', '*', 'TIMEOUT', '10'] ); }); diff --git a/packages/search/lib/commands/AGGREGATE.ts b/packages/search/lib/commands/AGGREGATE.ts index cb9652622a..0105b08268 100644 --- a/packages/search/lib/commands/AGGREGATE.ts +++ b/packages/search/lib/commands/AGGREGATE.ts @@ -1,7 +1,8 @@ -import { ArrayReply, BlobStringReply, Command, MapReply, NumberReply, RedisArgument, ReplyUnion, TypeMapping, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { ArrayReply, BlobStringReply, Command, MapReply, NumberReply, RedisArgument, ReplyUnion, TypeMapping, UnwrapReply } from '@redis/client/lib/RESP/types'; import { RediSearchProperty } from './CREATE'; -import { FtSearchParams, pushParamsArgument } from './SEARCH'; -import { pushVariadicArgument, transformTuplesReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { FtSearchParams, parseParamsArgument } from './SEARCH'; +import { transformTuplesReply } from '@redis/client/lib/commands/generic-transformers'; type LoadField = RediSearchProperty | { identifier: RediSearchProperty; @@ -137,12 +138,12 @@ export interface AggregateReply { }; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: false, - transformArguments(index: RedisArgument, query: RedisArgument, options?: FtAggregateOptions) { - const args = ['FT.AGGREGATE', index, query]; + parseCommand(parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: FtAggregateOptions) { + parser.push('FT.AGGREGATE', index, query); - return pushAggregateOptions(args, options); + return parseAggregateOptions(parser, options); }, transformReply: { 2: (rawReply: AggregateRawReply, preserve?: any, typeMapping?: TypeMapping): AggregateReply => { @@ -163,17 +164,17 @@ export default { unstableResp3: true } as const satisfies Command; -export function pushAggregateOptions(args: Array, options?: FtAggregateOptions) { +export function parseAggregateOptions(parser: CommandParser , options?: FtAggregateOptions) { if (options?.VERBATIM) { - args.push('VERBATIM'); + parser.push('VERBATIM'); } if (options?.ADDSCORES) { - args.push('ADDSCORES'); + parser.push('ADDSCORES'); } if (options?.LOAD) { - const length = args.push('LOAD', ''); + const args: Array = []; if (Array.isArray(options.LOAD)) { for (const load of options.LOAD) { @@ -183,36 +184,37 @@ export function pushAggregateOptions(args: Array, options?: FtAgg pushLoadField(args, options.LOAD); } - args[length - 1] = (args.length - length).toString(); + parser.push('LOAD'); + parser.pushVariadicWithLength(args); } if (options?.TIMEOUT !== undefined) { - args.push('TIMEOUT', options.TIMEOUT.toString()); + parser.push('TIMEOUT', options.TIMEOUT.toString()); } if (options?.STEPS) { for (const step of options.STEPS) { - args.push(step.type); + parser.push(step.type); switch (step.type) { case FT_AGGREGATE_STEPS.GROUPBY: if (!step.properties) { - args.push('0'); + parser.push('0'); } else { - pushVariadicArgument(args, step.properties); + parser.pushVariadicWithLength(step.properties); } if (Array.isArray(step.REDUCE)) { for (const reducer of step.REDUCE) { - pushGroupByReducer(args, reducer); + parseGroupByReducer(parser, reducer); } } else { - pushGroupByReducer(args, step.REDUCE); + parseGroupByReducer(parser, step.REDUCE); } break; case FT_AGGREGATE_STEPS.SORTBY: - const length = args.push(''); + const args: Array = []; if (Array.isArray(step.BY)) { for (const by of step.BY) { @@ -226,32 +228,30 @@ export function pushAggregateOptions(args: Array, options?: FtAgg args.push('MAX', step.MAX.toString()); } - args[length - 1] = (args.length - length).toString(); + parser.pushVariadicWithLength(args); break; case FT_AGGREGATE_STEPS.APPLY: - args.push(step.expression, 'AS', step.AS); + parser.push(step.expression, 'AS', step.AS); break; case FT_AGGREGATE_STEPS.LIMIT: - args.push(step.from.toString(), step.size.toString()); + parser.push(step.from.toString(), step.size.toString()); break; case FT_AGGREGATE_STEPS.FILTER: - args.push(step.expression); + parser.push(step.expression); break; } } } - pushParamsArgument(args, options?.PARAMS); + parseParamsArgument(parser, options?.PARAMS); if (options?.DIALECT !== undefined) { - args.push('DIALECT', options.DIALECT.toString()); + parser.push('DIALECT', options.DIALECT.toString()); } - - return args; } function pushLoadField(args: Array, toLoad: LoadField) { @@ -266,12 +266,12 @@ function pushLoadField(args: Array, toLoad: LoadField) { } } -function pushGroupByReducer(args: Array, reducer: GroupByReducers) { - args.push('REDUCE', reducer.type); +function parseGroupByReducer(parser: CommandParser, reducer: GroupByReducers) { + parser.push('REDUCE', reducer.type); switch (reducer.type) { case FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT: - args.push('0'); + parser.push('0'); break; case FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT_DISTINCT: @@ -282,15 +282,16 @@ function pushGroupByReducer(args: Array, reducer: GroupByReducers case FT_AGGREGATE_GROUP_BY_REDUCERS.AVG: case FT_AGGREGATE_GROUP_BY_REDUCERS.STDDEV: case FT_AGGREGATE_GROUP_BY_REDUCERS.TOLIST: - args.push('1', reducer.property); + parser.push('1', reducer.property); break; case FT_AGGREGATE_GROUP_BY_REDUCERS.QUANTILE: - args.push('2', reducer.property, reducer.quantile.toString()); + parser.push('2', reducer.property, reducer.quantile.toString()); break; case FT_AGGREGATE_GROUP_BY_REDUCERS.FIRST_VALUE: { - const length = args.push('', reducer.property) - 1; + const args: Array = [reducer.property]; + if (reducer.BY) { args.push('BY'); if (typeof reducer.BY === 'string' || reducer.BY instanceof Buffer) { @@ -303,17 +304,17 @@ function pushGroupByReducer(args: Array, reducer: GroupByReducers } } - args[length - 1] = (args.length - length).toString(); + parser.pushVariadicWithLength(args); break; } case FT_AGGREGATE_GROUP_BY_REDUCERS.RANDOM_SAMPLE: - args.push('2', reducer.property, reducer.sampleSize.toString()); + parser.push('2', reducer.property, reducer.sampleSize.toString()); break; } if (reducer.AS) { - args.push('AS', reducer.AS); + parser.push('AS', reducer.AS); } } diff --git a/packages/search/lib/commands/AGGREGATE_WITHCURSOR.spec.ts b/packages/search/lib/commands/AGGREGATE_WITHCURSOR.spec.ts index 9db3d945f9..57f46d1e32 100644 --- a/packages/search/lib/commands/AGGREGATE_WITHCURSOR.spec.ts +++ b/packages/search/lib/commands/AGGREGATE_WITHCURSOR.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('AGGREGATE WITHCURSOR', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - AGGREGATE_WITHCURSOR.transformArguments('index', '*'), + parseArgs(AGGREGATE_WITHCURSOR, 'index', '*'), ['FT.AGGREGATE', 'index', '*', 'WITHCURSOR'] ); }); it('with COUNT', () => { assert.deepEqual( - AGGREGATE_WITHCURSOR.transformArguments('index', '*', { + parseArgs(AGGREGATE_WITHCURSOR, 'index', '*', { COUNT: 1 }), ['FT.AGGREGATE', 'index', '*', 'WITHCURSOR', 'COUNT', '1'] @@ -22,7 +23,7 @@ describe('AGGREGATE WITHCURSOR', () => { it('with MAXIDLE', () => { assert.deepEqual( - AGGREGATE_WITHCURSOR.transformArguments('index', '*', { + parseArgs(AGGREGATE_WITHCURSOR, 'index', '*', { MAXIDLE: 1 }), ['FT.AGGREGATE', 'index', '*', 'WITHCURSOR', 'MAXIDLE', '1'] diff --git a/packages/search/lib/commands/AGGREGATE_WITHCURSOR.ts b/packages/search/lib/commands/AGGREGATE_WITHCURSOR.ts index cffb86b8b4..f9a7e75942 100644 --- a/packages/search/lib/commands/AGGREGATE_WITHCURSOR.ts +++ b/packages/search/lib/commands/AGGREGATE_WITHCURSOR.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, ReplyUnion, NumberReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, ReplyUnion, NumberReply } from '@redis/client/lib/RESP/types'; import AGGREGATE, { AggregateRawReply, AggregateReply, FtAggregateOptions } from './AGGREGATE'; export interface FtAggregateWithCursorOptions extends FtAggregateOptions { @@ -17,21 +18,18 @@ export interface AggregateWithCursorReply extends AggregateReply { } export default { - FIRST_KEY_INDEX: AGGREGATE.FIRST_KEY_INDEX, IS_READ_ONLY: AGGREGATE.IS_READ_ONLY, - transformArguments(index: RedisArgument, query: RedisArgument, options?: FtAggregateWithCursorOptions) { - const args = AGGREGATE.transformArguments(index, query, options); - args.push('WITHCURSOR'); + parseCommand(parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: FtAggregateWithCursorOptions) { + AGGREGATE.parseCommand(parser, index, query, options); + parser.push('WITHCURSOR'); if (options?.COUNT !== undefined) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } if(options?.MAXIDLE !== undefined) { - args.push('MAXIDLE', options.MAXIDLE.toString()); + parser.push('MAXIDLE', options.MAXIDLE.toString()); } - - return args; }, transformReply: { 2: (reply: AggregateWithCursorRawReply): AggregateWithCursorReply => { @@ -44,4 +42,3 @@ export default { }, unstableResp3: true } as const satisfies Command; - diff --git a/packages/search/lib/commands/ALIASADD.spec.ts b/packages/search/lib/commands/ALIASADD.spec.ts index 3a5d02175f..b8332aed6a 100644 --- a/packages/search/lib/commands/ALIASADD.spec.ts +++ b/packages/search/lib/commands/ALIASADD.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ALIASADD from './ALIASADD'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.ALIASADD', () => { it('transformArguments', () => { assert.deepEqual( - ALIASADD.transformArguments('alias', 'index'), + parseArgs(ALIASADD, 'alias', 'index'), ['FT.ALIASADD', 'alias', 'index'] ); }); diff --git a/packages/search/lib/commands/ALIASADD.ts b/packages/search/lib/commands/ALIASADD.ts index 648e1fef97..db8eb54326 100644 --- a/packages/search/lib/commands/ALIASADD.ts +++ b/packages/search/lib/commands/ALIASADD.ts @@ -1,10 +1,11 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(alias: RedisArgument, index: RedisArgument) { - return ['FT.ALIASADD', alias, index]; + parseCommand(parser: CommandParser, alias: RedisArgument, index: RedisArgument) { + parser.push('FT.ALIASADD', alias, index); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/ALIASDEL.spec.ts b/packages/search/lib/commands/ALIASDEL.spec.ts index 3842d01b14..19c2473f8c 100644 --- a/packages/search/lib/commands/ALIASDEL.spec.ts +++ b/packages/search/lib/commands/ALIASDEL.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ALIASDEL from './ALIASDEL'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.ALIASDEL', () => { it('transformArguments', () => { assert.deepEqual( - ALIASDEL.transformArguments('alias'), + parseArgs(ALIASDEL, 'alias'), ['FT.ALIASDEL', 'alias'] ); }); diff --git a/packages/search/lib/commands/ALIASDEL.ts b/packages/search/lib/commands/ALIASDEL.ts index 40cc45a19d..3e4b70a194 100644 --- a/packages/search/lib/commands/ALIASDEL.ts +++ b/packages/search/lib/commands/ALIASDEL.ts @@ -1,10 +1,11 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(alias: RedisArgument) { - return ['FT.ALIASDEL', alias]; + parseCommand(parser: CommandParser, alias: RedisArgument) { + parser.push('FT.ALIASDEL', alias); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/ALIASUPDATE.spec.ts b/packages/search/lib/commands/ALIASUPDATE.spec.ts index a0e7431af6..f23af30229 100644 --- a/packages/search/lib/commands/ALIASUPDATE.spec.ts +++ b/packages/search/lib/commands/ALIASUPDATE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ALIASUPDATE from './ALIASUPDATE'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.ALIASUPDATE', () => { it('transformArguments', () => { assert.deepEqual( - ALIASUPDATE.transformArguments('alias', 'index'), + parseArgs(ALIASUPDATE, 'alias', 'index'), ['FT.ALIASUPDATE', 'alias', 'index'] ); }); diff --git a/packages/search/lib/commands/ALIASUPDATE.ts b/packages/search/lib/commands/ALIASUPDATE.ts index e2b72cfe64..46f0aa3e02 100644 --- a/packages/search/lib/commands/ALIASUPDATE.ts +++ b/packages/search/lib/commands/ALIASUPDATE.ts @@ -1,10 +1,11 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(alias: RedisArgument, index: RedisArgument) { - return ['FT.ALIASUPDATE', alias, index]; + parseCommand(parser: CommandParser, alias: RedisArgument, index: RedisArgument) { + parser.push('FT.ALIASUPDATE', alias, index); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/ALTER.spec.ts b/packages/search/lib/commands/ALTER.spec.ts index 6cac0be40c..c34f7e045d 100644 --- a/packages/search/lib/commands/ALTER.spec.ts +++ b/packages/search/lib/commands/ALTER.spec.ts @@ -2,12 +2,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ALTER from './ALTER'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.ALTER', () => { describe('transformArguments', () => { it('with NOINDEX', () => { assert.deepEqual( - ALTER.transformArguments('index', { + parseArgs(ALTER, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, NOINDEX: true, diff --git a/packages/search/lib/commands/ALTER.ts b/packages/search/lib/commands/ALTER.ts index d5587b2397..4cde32e6ad 100644 --- a/packages/search/lib/commands/ALTER.ts +++ b/packages/search/lib/commands/ALTER.ts @@ -1,13 +1,13 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { RediSearchSchema, pushSchema } from './CREATE'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; +import { RediSearchSchema, parseSchema } from './CREATE'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, schema: RediSearchSchema) { - const args = ['FT.ALTER', index, 'SCHEMA', 'ADD']; - pushSchema(args, schema); - return args; + parseCommand(parser: CommandParser, index: RedisArgument, schema: RediSearchSchema) { + parser.push('FT.ALTER', index, 'SCHEMA', 'ADD'); + parseSchema(parser, schema); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/CONFIG_GET.spec.ts b/packages/search/lib/commands/CONFIG_GET.spec.ts index 7ef2a3536b..598a2a9ac4 100644 --- a/packages/search/lib/commands/CONFIG_GET.spec.ts +++ b/packages/search/lib/commands/CONFIG_GET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_GET from './CONFIG_GET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.CONFIG GET', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_GET.transformArguments('TIMEOUT'), + parseArgs(CONFIG_GET, 'TIMEOUT'), ['FT.CONFIG', 'GET', 'TIMEOUT'] ); }); diff --git a/packages/search/lib/commands/CONFIG_GET.ts b/packages/search/lib/commands/CONFIG_GET.ts index f96461e869..9c0be73e2e 100644 --- a/packages/search/lib/commands/CONFIG_GET.ts +++ b/packages/search/lib/commands/CONFIG_GET.ts @@ -1,10 +1,11 @@ -import { ArrayReply, TuplesReply, BlobStringReply, NullReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { ArrayReply, TuplesReply, BlobStringReply, NullReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(option: string) { - return ['FT.CONFIG', 'GET', option]; + parseCommand(parser: CommandParser, option: string) { + parser.push('FT.CONFIG', 'GET', option); }, transformReply(reply: UnwrapReply>>) { const transformedReply: Record = Object.create(null); diff --git a/packages/search/lib/commands/CONFIG_SET.spec.ts b/packages/search/lib/commands/CONFIG_SET.spec.ts index 3b20f2eac5..71a4e69f26 100644 --- a/packages/search/lib/commands/CONFIG_SET.spec.ts +++ b/packages/search/lib/commands/CONFIG_SET.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CONFIG_SET from './CONFIG_SET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.CONFIG SET', () => { it('transformArguments', () => { assert.deepEqual( - CONFIG_SET.transformArguments('TIMEOUT', '500'), + parseArgs(CONFIG_SET, 'TIMEOUT', '500'), ['FT.CONFIG', 'SET', 'TIMEOUT', '500'] ); }); diff --git a/packages/search/lib/commands/CONFIG_SET.ts b/packages/search/lib/commands/CONFIG_SET.ts index ac001bf68a..ae57dd7d8f 100644 --- a/packages/search/lib/commands/CONFIG_SET.ts +++ b/packages/search/lib/commands/CONFIG_SET.ts @@ -1,14 +1,15 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; // using `string & {}` to avoid TS widening the type to `string` // TODO type FtConfigProperties = 'a' | 'b' | (string & {}) | Buffer; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(property: FtConfigProperties, value: RedisArgument) { - return ['FT.CONFIG', 'SET', property, value]; + parseCommand(parser: CommandParser, property: FtConfigProperties, value: RedisArgument) { + parser.push('FT.CONFIG', 'SET', property, value); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/CREATE.spec.ts b/packages/search/lib/commands/CREATE.spec.ts index bc48691bd5..58888fb7ce 100644 --- a/packages/search/lib/commands/CREATE.spec.ts +++ b/packages/search/lib/commands/CREATE.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CREATE, { SCHEMA_FIELD_TYPE, SCHEMA_TEXT_FIELD_PHONETIC, SCHEMA_VECTOR_FIELD_ALGORITHM, REDISEARCH_LANGUAGE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.CREATE', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - CREATE.transformArguments('index', {}), + parseArgs(CREATE, 'index', {}), ['FT.CREATE', 'index', 'SCHEMA'] ); }); @@ -15,7 +16,7 @@ describe('FT.CREATE', () => { describe('TEXT', () => { it('without options', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: SCHEMA_FIELD_TYPE.TEXT }), ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT'] @@ -24,7 +25,7 @@ describe('FT.CREATE', () => { it('with NOSTEM', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, NOSTEM: true @@ -36,7 +37,7 @@ describe('FT.CREATE', () => { it('with WEIGHT', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, WEIGHT: 1 @@ -48,7 +49,7 @@ describe('FT.CREATE', () => { it('with PHONETIC', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, PHONETIC: SCHEMA_TEXT_FIELD_PHONETIC.DM_EN @@ -60,7 +61,7 @@ describe('FT.CREATE', () => { it('with WITHSUFFIXTRIE', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, WITHSUFFIXTRIE: true @@ -73,7 +74,7 @@ describe('FT.CREATE', () => { it('NUMERIC', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: SCHEMA_FIELD_TYPE.NUMERIC }), ['FT.CREATE', 'index', 'SCHEMA', 'field', 'NUMERIC'] @@ -82,7 +83,7 @@ describe('FT.CREATE', () => { it('GEO', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: SCHEMA_FIELD_TYPE.GEO }), ['FT.CREATE', 'index', 'SCHEMA', 'field', 'GEO'] @@ -93,7 +94,7 @@ describe('FT.CREATE', () => { describe('without options', () => { it('SCHEMA_FIELD_TYPE.TAG', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: SCHEMA_FIELD_TYPE.TAG }), ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG'] @@ -102,7 +103,7 @@ describe('FT.CREATE', () => { it('{ type: SCHEMA_FIELD_TYPE.TAG }', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TAG } @@ -114,7 +115,7 @@ describe('FT.CREATE', () => { it('with SEPARATOR', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TAG, SEPARATOR: 'separator' @@ -126,7 +127,7 @@ describe('FT.CREATE', () => { it('with CASESENSITIVE', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TAG, CASESENSITIVE: true @@ -138,7 +139,7 @@ describe('FT.CREATE', () => { it('with WITHSUFFIXTRIE', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TAG, WITHSUFFIXTRIE: true @@ -150,7 +151,7 @@ describe('FT.CREATE', () => { it('with INDEXEMPTY', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TAG, INDEXEMPTY: true @@ -164,7 +165,7 @@ describe('FT.CREATE', () => { describe('VECTOR', () => { it('Flat algorithm', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.VECTOR, ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.FLAT, @@ -185,7 +186,7 @@ describe('FT.CREATE', () => { it('HNSW algorithm', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.VECTOR, ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW, @@ -211,7 +212,7 @@ describe('FT.CREATE', () => { describe('without options', () => { it('SCHEMA_FIELD_TYPE.GEOSHAPE', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: SCHEMA_FIELD_TYPE.GEOSHAPE }), ['FT.CREATE', 'index', 'SCHEMA', 'field', 'GEOSHAPE'] @@ -220,7 +221,7 @@ describe('FT.CREATE', () => { it('{ type: SCHEMA_FIELD_TYPE.GEOSHAPE }', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.GEOSHAPE } @@ -232,7 +233,7 @@ describe('FT.CREATE', () => { it('with COORD_SYSTEM', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.GEOSHAPE, COORD_SYSTEM: 'SPHERICAL' @@ -245,7 +246,7 @@ describe('FT.CREATE', () => { it('with AS', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, AS: 'as' @@ -258,7 +259,7 @@ describe('FT.CREATE', () => { describe('with SORTABLE', () => { it('true', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, SORTABLE: true @@ -270,7 +271,7 @@ describe('FT.CREATE', () => { it('UNF', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, SORTABLE: 'UNF' @@ -283,7 +284,7 @@ describe('FT.CREATE', () => { it('with NOINDEX', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, NOINDEX: true @@ -295,7 +296,7 @@ describe('FT.CREATE', () => { it('with INDEXMISSING', () => { assert.deepEqual( - CREATE.transformArguments('index', { + parseArgs(CREATE, 'index', { field: { type: SCHEMA_FIELD_TYPE.TEXT, INDEXMISSING: true @@ -308,7 +309,7 @@ describe('FT.CREATE', () => { it('with ON', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { ON: 'HASH' }), ['FT.CREATE', 'index', 'ON', 'HASH', 'SCHEMA'] @@ -318,7 +319,7 @@ describe('FT.CREATE', () => { describe('with PREFIX', () => { it('string', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { PREFIX: 'prefix' }), ['FT.CREATE', 'index', 'PREFIX', '1', 'prefix', 'SCHEMA'] @@ -327,7 +328,7 @@ describe('FT.CREATE', () => { it('Array', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { PREFIX: ['1', '2'] }), ['FT.CREATE', 'index', 'PREFIX', '2', '1', '2', 'SCHEMA'] @@ -337,7 +338,7 @@ describe('FT.CREATE', () => { it('with FILTER', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { FILTER: '@field != ""' }), ['FT.CREATE', 'index', 'FILTER', '@field != ""', 'SCHEMA'] @@ -346,7 +347,7 @@ describe('FT.CREATE', () => { it('with LANGUAGE', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { LANGUAGE: REDISEARCH_LANGUAGE.ARABIC }), ['FT.CREATE', 'index', 'LANGUAGE', REDISEARCH_LANGUAGE.ARABIC, 'SCHEMA'] @@ -355,7 +356,7 @@ describe('FT.CREATE', () => { it('with LANGUAGE_FIELD', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { LANGUAGE_FIELD: '@field' }), ['FT.CREATE', 'index', 'LANGUAGE_FIELD', '@field', 'SCHEMA'] @@ -364,7 +365,7 @@ describe('FT.CREATE', () => { it('with SCORE', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { SCORE: 1 }), ['FT.CREATE', 'index', 'SCORE', '1', 'SCHEMA'] @@ -373,7 +374,7 @@ describe('FT.CREATE', () => { it('with SCORE_FIELD', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { SCORE_FIELD: '@field' }), ['FT.CREATE', 'index', 'SCORE_FIELD', '@field', 'SCHEMA'] @@ -382,7 +383,7 @@ describe('FT.CREATE', () => { it('with MAXTEXTFIELDS', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { MAXTEXTFIELDS: true }), ['FT.CREATE', 'index', 'MAXTEXTFIELDS', 'SCHEMA'] @@ -391,7 +392,7 @@ describe('FT.CREATE', () => { it('with TEMPORARY', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { TEMPORARY: 1 }), ['FT.CREATE', 'index', 'TEMPORARY', '1', 'SCHEMA'] @@ -400,7 +401,7 @@ describe('FT.CREATE', () => { it('with NOOFFSETS', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { NOOFFSETS: true }), ['FT.CREATE', 'index', 'NOOFFSETS', 'SCHEMA'] @@ -409,7 +410,7 @@ describe('FT.CREATE', () => { it('with NOHL', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { NOHL: true }), ['FT.CREATE', 'index', 'NOHL', 'SCHEMA'] @@ -418,7 +419,7 @@ describe('FT.CREATE', () => { it('with NOFIELDS', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { NOFIELDS: true }), ['FT.CREATE', 'index', 'NOFIELDS', 'SCHEMA'] @@ -427,7 +428,7 @@ describe('FT.CREATE', () => { it('with NOFREQS', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { NOFREQS: true }), ['FT.CREATE', 'index', 'NOFREQS', 'SCHEMA'] @@ -436,7 +437,7 @@ describe('FT.CREATE', () => { it('with SKIPINITIALSCAN', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { SKIPINITIALSCAN: true }), ['FT.CREATE', 'index', 'SKIPINITIALSCAN', 'SCHEMA'] @@ -446,7 +447,7 @@ describe('FT.CREATE', () => { describe('with STOPWORDS', () => { it('string', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { STOPWORDS: 'stopword' }), ['FT.CREATE', 'index', 'STOPWORDS', '1', 'stopword', 'SCHEMA'] @@ -455,7 +456,7 @@ describe('FT.CREATE', () => { it('Array', () => { assert.deepEqual( - CREATE.transformArguments('index', {}, { + parseArgs(CREATE, 'index', {}, { STOPWORDS: ['1', '2'] }), ['FT.CREATE', 'index', 'STOPWORDS', '2', '1', '2', 'SCHEMA'] diff --git a/packages/search/lib/commands/CREATE.ts b/packages/search/lib/commands/CREATE.ts index 2951e56f09..d0096282f3 100644 --- a/packages/search/lib/commands/CREATE.ts +++ b/packages/search/lib/commands/CREATE.ts @@ -1,5 +1,6 @@ -import { RedisArgument, SimpleStringReply, Command, CommandArguments } from '@redis/client/lib/RESP/types'; -import { RedisVariadicArgument, pushOptionalVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument, parseOptionalVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export const SCHEMA_FIELD_TYPE = { TEXT: 'TEXT', @@ -102,93 +103,93 @@ export interface RediSearchSchema { ); } -function pushCommonSchemaFieldOptions(args: CommandArguments, fieldOptions: SchemaCommonField) { +function parseCommonSchemaFieldOptions(parser: CommandParser, fieldOptions: SchemaCommonField) { if (fieldOptions.SORTABLE) { - args.push('SORTABLE'); + parser.push('SORTABLE'); if (fieldOptions.SORTABLE === 'UNF') { - args.push('UNF'); + parser.push('UNF'); } } if (fieldOptions.NOINDEX) { - args.push('NOINDEX'); + parser.push('NOINDEX'); } } -export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { +export function parseSchema(parser: CommandParser, schema: RediSearchSchema) { for (const [field, fieldOptions] of Object.entries(schema)) { - args.push(field); + parser.push(field); if (typeof fieldOptions === 'string') { - args.push(fieldOptions); + parser.push(fieldOptions); continue; } if (fieldOptions.AS) { - args.push('AS', fieldOptions.AS); + parser.push('AS', fieldOptions.AS); } - args.push(fieldOptions.type); + parser.push(fieldOptions.type); if (fieldOptions.INDEXMISSING) { - args.push('INDEXMISSING'); + parser.push('INDEXMISSING'); } switch (fieldOptions.type) { case SCHEMA_FIELD_TYPE.TEXT: if (fieldOptions.NOSTEM) { - args.push('NOSTEM'); + parser.push('NOSTEM'); } if (fieldOptions.WEIGHT) { - args.push('WEIGHT', fieldOptions.WEIGHT.toString()); + parser.push('WEIGHT', fieldOptions.WEIGHT.toString()); } if (fieldOptions.PHONETIC) { - args.push('PHONETIC', fieldOptions.PHONETIC); + parser.push('PHONETIC', fieldOptions.PHONETIC); } if (fieldOptions.WITHSUFFIXTRIE) { - args.push('WITHSUFFIXTRIE'); + parser.push('WITHSUFFIXTRIE'); } if (fieldOptions.INDEXEMPTY) { - args.push('INDEXEMPTY'); + parser.push('INDEXEMPTY'); } - pushCommonSchemaFieldOptions(args, fieldOptions) + parseCommonSchemaFieldOptions(parser, fieldOptions) break; case SCHEMA_FIELD_TYPE.NUMERIC: case SCHEMA_FIELD_TYPE.GEO: - pushCommonSchemaFieldOptions(args, fieldOptions) + parseCommonSchemaFieldOptions(parser, fieldOptions) break; case SCHEMA_FIELD_TYPE.TAG: if (fieldOptions.SEPARATOR) { - args.push('SEPARATOR', fieldOptions.SEPARATOR); + parser.push('SEPARATOR', fieldOptions.SEPARATOR); } if (fieldOptions.CASESENSITIVE) { - args.push('CASESENSITIVE'); + parser.push('CASESENSITIVE'); } if (fieldOptions.WITHSUFFIXTRIE) { - args.push('WITHSUFFIXTRIE'); + parser.push('WITHSUFFIXTRIE'); } if (fieldOptions.INDEXEMPTY) { - args.push('INDEXEMPTY'); + parser.push('INDEXEMPTY'); } - pushCommonSchemaFieldOptions(args, fieldOptions) + parseCommonSchemaFieldOptions(parser, fieldOptions) break; case SCHEMA_FIELD_TYPE.VECTOR: - args.push(fieldOptions.ALGORITHM); + parser.push(fieldOptions.ALGORITHM); - const lengthIndex = args.push('') - 1; + const args: Array = []; args.push( 'TYPE', fieldOptions.TYPE, @@ -200,7 +201,7 @@ export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { args.push('INITIAL_CAP', fieldOptions.INITIAL_CAP.toString()); } - switch (fieldOptions.ALGORITHM) { + switch (fieldOptions.ALGORITHM) { case SCHEMA_VECTOR_FIELD_ALGORITHM.FLAT: if (fieldOptions.BLOCK_SIZE) { args.push('BLOCK_SIZE', fieldOptions.BLOCK_SIZE.toString()); @@ -223,13 +224,13 @@ export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { break; } - args[lengthIndex] = (args.length - lengthIndex - 1).toString(); + parser.pushVariadicWithLength(args); break; case SCHEMA_FIELD_TYPE.GEOSHAPE: if (fieldOptions.COORD_SYSTEM !== undefined) { - args.push('COORD_SYSTEM', fieldOptions.COORD_SYSTEM); + parser.push('COORD_SYSTEM', fieldOptions.COORD_SYSTEM); } break; @@ -289,74 +290,72 @@ export interface CreateOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, schema: RediSearchSchema, options?: CreateOptions) { - const args = ['FT.CREATE', index]; + parseCommand(parser: CommandParser, index: RedisArgument, schema: RediSearchSchema, options?: CreateOptions) { + parser.push('FT.CREATE', index); if (options?.ON) { - args.push('ON', options.ON); + parser.push('ON', options.ON); } - pushOptionalVariadicArgument(args, 'PREFIX', options?.PREFIX); + parseOptionalVariadicArgument(parser, 'PREFIX', options?.PREFIX); if (options?.FILTER) { - args.push('FILTER', options.FILTER); + parser.push('FILTER', options.FILTER); } if (options?.LANGUAGE) { - args.push('LANGUAGE', options.LANGUAGE); + parser.push('LANGUAGE', options.LANGUAGE); } if (options?.LANGUAGE_FIELD) { - args.push('LANGUAGE_FIELD', options.LANGUAGE_FIELD); + parser.push('LANGUAGE_FIELD', options.LANGUAGE_FIELD); } if (options?.SCORE) { - args.push('SCORE', options.SCORE.toString()); + parser.push('SCORE', options.SCORE.toString()); } if (options?.SCORE_FIELD) { - args.push('SCORE_FIELD', options.SCORE_FIELD); + parser.push('SCORE_FIELD', options.SCORE_FIELD); } // if (options?.PAYLOAD_FIELD) { - // args.push('PAYLOAD_FIELD', options.PAYLOAD_FIELD); + // parser.push('PAYLOAD_FIELD', options.PAYLOAD_FIELD); // } if (options?.MAXTEXTFIELDS) { - args.push('MAXTEXTFIELDS'); + parser.push('MAXTEXTFIELDS'); } if (options?.TEMPORARY) { - args.push('TEMPORARY', options.TEMPORARY.toString()); + parser.push('TEMPORARY', options.TEMPORARY.toString()); } if (options?.NOOFFSETS) { - args.push('NOOFFSETS'); + parser.push('NOOFFSETS'); } if (options?.NOHL) { - args.push('NOHL'); + parser.push('NOHL'); } if (options?.NOFIELDS) { - args.push('NOFIELDS'); + parser.push('NOFIELDS'); } if (options?.NOFREQS) { - args.push('NOFREQS'); + parser.push('NOFREQS'); } if (options?.SKIPINITIALSCAN) { - args.push('SKIPINITIALSCAN'); + parser.push('SKIPINITIALSCAN'); } - pushOptionalVariadicArgument(args, 'STOPWORDS', options?.STOPWORDS); - args.push('SCHEMA'); - pushSchema(args, schema); - - return args; + parseOptionalVariadicArgument(parser, 'STOPWORDS', options?.STOPWORDS); + parser.push('SCHEMA'); + parseSchema(parser, schema); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/CURSOR_DEL.spec.ts b/packages/search/lib/commands/CURSOR_DEL.spec.ts index 8e9a7cf9ae..230a5fd0fe 100644 --- a/packages/search/lib/commands/CURSOR_DEL.spec.ts +++ b/packages/search/lib/commands/CURSOR_DEL.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CURSOR_DEL from './CURSOR_DEL'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.CURSOR DEL', () => { it('transformArguments', () => { assert.deepEqual( - CURSOR_DEL.transformArguments('index', 0), + parseArgs(CURSOR_DEL, 'index', 0), ['FT.CURSOR', 'DEL', 'index', '0'] ); }); diff --git a/packages/search/lib/commands/CURSOR_DEL.ts b/packages/search/lib/commands/CURSOR_DEL.ts index afccd695ff..1ea4b46c8b 100644 --- a/packages/search/lib/commands/CURSOR_DEL.ts +++ b/packages/search/lib/commands/CURSOR_DEL.ts @@ -1,10 +1,11 @@ -import { SimpleStringReply, Command, RedisArgument, NumberReply, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument, NumberReply, UnwrapReply } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, cursorId: UnwrapReply) { - return ['FT.CURSOR', 'DEL', index, cursorId.toString()]; + parseCommand(parser: CommandParser, index: RedisArgument, cursorId: UnwrapReply) { + parser.push('FT.CURSOR', 'DEL', index, cursorId.toString()); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/CURSOR_READ.spec.ts b/packages/search/lib/commands/CURSOR_READ.spec.ts index 5999d4a7c1..42dca0c575 100644 --- a/packages/search/lib/commands/CURSOR_READ.spec.ts +++ b/packages/search/lib/commands/CURSOR_READ.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CURSOR_READ from './CURSOR_READ'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.CURSOR READ', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - CURSOR_READ.transformArguments('index', 0), + parseArgs(CURSOR_READ, 'index', '0'), ['FT.CURSOR', 'READ', 'index', '0'] ); }); it('with COUNT', () => { assert.deepEqual( - CURSOR_READ.transformArguments('index', 0, { + parseArgs(CURSOR_READ, 'index', '0', { COUNT: 1 }), ['FT.CURSOR', 'READ', 'index', '0', 'COUNT', '1'] diff --git a/packages/search/lib/commands/CURSOR_READ.ts b/packages/search/lib/commands/CURSOR_READ.ts index d08b22ba90..d23a0f0bd1 100644 --- a/packages/search/lib/commands/CURSOR_READ.ts +++ b/packages/search/lib/commands/CURSOR_READ.ts @@ -1,4 +1,5 @@ -import { RedisArgument, Command, UnwrapReply, NumberReply } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, NumberReply, UnwrapReply } from '@redis/client/lib/RESP/types'; import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR'; export interface FtCursorReadOptions { @@ -6,16 +7,14 @@ export interface FtCursorReadOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, cursor: UnwrapReply, options?: FtCursorReadOptions) { - const args = ['FT.CURSOR', 'READ', index, cursor.toString()]; + parseCommand(parser: CommandParser, index: RedisArgument, cursor: UnwrapReply, options?: FtCursorReadOptions) { + parser.push('FT.CURSOR', 'READ', index, cursor.toString()); if (options?.COUNT !== undefined) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } - - return args; }, transformReply: AGGREGATE_WITHCURSOR.transformReply, unstableResp3: true diff --git a/packages/search/lib/commands/DICTADD.spec.ts b/packages/search/lib/commands/DICTADD.spec.ts index c18502ea4d..4707db02dc 100644 --- a/packages/search/lib/commands/DICTADD.spec.ts +++ b/packages/search/lib/commands/DICTADD.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DICTADD from './DICTADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.DICTADD', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - DICTADD.transformArguments('dictionary', 'term'), + parseArgs(DICTADD, 'dictionary', 'term'), ['FT.DICTADD', 'dictionary', 'term'] ); }); it('Array', () => { assert.deepEqual( - DICTADD.transformArguments('dictionary', ['1', '2']), + parseArgs(DICTADD, 'dictionary', ['1', '2']), ['FT.DICTADD', 'dictionary', '1', '2'] ); }); diff --git a/packages/search/lib/commands/DICTADD.ts b/packages/search/lib/commands/DICTADD.ts index f633d58b1f..67f94a82c1 100644 --- a/packages/search/lib/commands/DICTADD.ts +++ b/packages/search/lib/commands/DICTADD.ts @@ -1,11 +1,13 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { pushVariadicArguments, RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(dictionary: RedisArgument, term: RedisVariadicArgument) { - return pushVariadicArguments(['FT.DICTADD', dictionary], term); + parseCommand(parser: CommandParser, dictionary: RedisArgument, term: RedisVariadicArgument) { + parser.push('FT.DICTADD', dictionary); + parser.pushVariadic(term); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/search/lib/commands/DICTDEL.spec.ts b/packages/search/lib/commands/DICTDEL.spec.ts index a7ca1b35cd..a9f997bdf3 100644 --- a/packages/search/lib/commands/DICTDEL.spec.ts +++ b/packages/search/lib/commands/DICTDEL.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DICTDEL from './DICTDEL'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.DICTDEL', () => { describe('transformArguments', () => { it('string', () => { assert.deepEqual( - DICTDEL.transformArguments('dictionary', 'term'), + parseArgs(DICTDEL, 'dictionary', 'term'), ['FT.DICTDEL', 'dictionary', 'term'] ); }); it('Array', () => { assert.deepEqual( - DICTDEL.transformArguments('dictionary', ['1', '2']), + parseArgs(DICTDEL, 'dictionary', ['1', '2']), ['FT.DICTDEL', 'dictionary', '1', '2'] ); }); diff --git a/packages/search/lib/commands/DICTDEL.ts b/packages/search/lib/commands/DICTDEL.ts index 087211751e..9b0bda3a7a 100644 --- a/packages/search/lib/commands/DICTDEL.ts +++ b/packages/search/lib/commands/DICTDEL.ts @@ -1,11 +1,13 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { pushVariadicArguments, RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(dictionary: RedisArgument, term: RedisVariadicArgument) { - return pushVariadicArguments(['FT.DICTDEL', dictionary], term); + parseCommand(parser: CommandParser, dictionary: RedisArgument, term: RedisVariadicArgument) { + parser.push('FT.DICTDEL', dictionary); + parser.pushVariadic(term); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/search/lib/commands/DICTDUMP.spec.ts b/packages/search/lib/commands/DICTDUMP.spec.ts index fe8e944118..1a3faa9dc9 100644 --- a/packages/search/lib/commands/DICTDUMP.spec.ts +++ b/packages/search/lib/commands/DICTDUMP.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DICTDUMP from './DICTDUMP'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.DICTDUMP', () => { it('transformArguments', () => { assert.deepEqual( - DICTDUMP.transformArguments('dictionary'), + parseArgs(DICTDUMP, 'dictionary'), ['FT.DICTDUMP', 'dictionary'] ); }); diff --git a/packages/search/lib/commands/DICTDUMP.ts b/packages/search/lib/commands/DICTDUMP.ts index f542403cc5..00dd5aba4e 100644 --- a/packages/search/lib/commands/DICTDUMP.ts +++ b/packages/search/lib/commands/DICTDUMP.ts @@ -1,10 +1,11 @@ -import { RedisArgument, ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(dictionary: RedisArgument) { - return ['FT.DICTDUMP', dictionary]; + parseCommand(parser: CommandParser, dictionary: RedisArgument) { + parser.push('FT.DICTDUMP', dictionary); }, transformReply: { 2: undefined as unknown as () => ArrayReply, diff --git a/packages/search/lib/commands/DROPINDEX.spec.ts b/packages/search/lib/commands/DROPINDEX.spec.ts index 5fcbaca08c..f1f0b0efdd 100644 --- a/packages/search/lib/commands/DROPINDEX.spec.ts +++ b/packages/search/lib/commands/DROPINDEX.spec.ts @@ -2,19 +2,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DROPINDEX from './DROPINDEX'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.DROPINDEX', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - DROPINDEX.transformArguments('index'), + parseArgs(DROPINDEX, 'index'), ['FT.DROPINDEX', 'index'] ); }); it('with DD', () => { assert.deepEqual( - DROPINDEX.transformArguments('index', { DD: true }), + parseArgs(DROPINDEX, 'index', { DD: true }), ['FT.DROPINDEX', 'index', 'DD'] ); }); diff --git a/packages/search/lib/commands/DROPINDEX.ts b/packages/search/lib/commands/DROPINDEX.ts index 64fe9711e7..e7be806ac1 100644 --- a/packages/search/lib/commands/DROPINDEX.ts +++ b/packages/search/lib/commands/DROPINDEX.ts @@ -1,20 +1,19 @@ -import { RedisArgument, SimpleStringReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface FtDropIndexOptions { DD?: true; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, options?: FtDropIndexOptions) { - const args = ['FT.DROPINDEX', index]; + parseCommand(parser: CommandParser, index: RedisArgument, options?: FtDropIndexOptions) { + parser.push('FT.DROPINDEX', index); if (options?.DD) { - args.push('DD'); + parser.push('DD'); } - - return args; }, transformReply: { 2: undefined as unknown as () => SimpleStringReply<'OK'>, diff --git a/packages/search/lib/commands/EXPLAIN.spec.ts b/packages/search/lib/commands/EXPLAIN.spec.ts index e8b3555957..ddc551fbd7 100644 --- a/packages/search/lib/commands/EXPLAIN.spec.ts +++ b/packages/search/lib/commands/EXPLAIN.spec.ts @@ -1,5 +1,6 @@ import { strict as assert } from 'node:assert'; import EXPLAIN from './EXPLAIN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; import testUtils, { GLOBAL } from '../test-utils'; import { SCHEMA_FIELD_TYPE } from './CREATE'; @@ -7,14 +8,14 @@ describe('EXPLAIN', () => { describe('transformArguments', () => { it('simple', () => { assert.deepEqual( - EXPLAIN.transformArguments('index', '*'), + parseArgs(EXPLAIN, 'index', '*'), ['FT.EXPLAIN', 'index', '*'] ); }); it('with PARAMS', () => { assert.deepEqual( - EXPLAIN.transformArguments('index', '*', { + parseArgs(EXPLAIN, 'index', '*', { PARAMS: { param: 'value' } @@ -25,7 +26,7 @@ describe('EXPLAIN', () => { it('with DIALECT', () => { assert.deepEqual( - EXPLAIN.transformArguments('index', '*', { + parseArgs(EXPLAIN, 'index', '*', { DIALECT: 1 }), ['FT.EXPLAIN', 'index', '*', 'DIALECT', '1'] diff --git a/packages/search/lib/commands/EXPLAIN.ts b/packages/search/lib/commands/EXPLAIN.ts index 0ad84feb68..deb75229b5 100644 --- a/packages/search/lib/commands/EXPLAIN.ts +++ b/packages/search/lib/commands/EXPLAIN.ts @@ -1,5 +1,6 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { FtSearchParams, pushParamsArgument } from './SEARCH'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; +import { FtSearchParams, parseParamsArgument } from './SEARCH'; export interface FtExplainOptions { PARAMS?: FtSearchParams; @@ -7,22 +8,21 @@ export interface FtExplainOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: FtExplainOptions ) { - const args = ['FT.EXPLAIN', index, query]; + parser.push('FT.EXPLAIN', index, query); - pushParamsArgument(args, options?.PARAMS); + parseParamsArgument(parser, options?.PARAMS); if (options?.DIALECT) { - args.push('DIALECT', options.DIALECT.toString()); + parser.push('DIALECT', options.DIALECT.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply } as const satisfies Command; diff --git a/packages/search/lib/commands/EXPLAINCLI.spec.ts b/packages/search/lib/commands/EXPLAINCLI.spec.ts index 3bffcf5fe5..cf46a1740c 100644 --- a/packages/search/lib/commands/EXPLAINCLI.spec.ts +++ b/packages/search/lib/commands/EXPLAINCLI.spec.ts @@ -1,10 +1,11 @@ import { strict as assert } from 'node:assert'; import EXPLAINCLI from './EXPLAINCLI'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('EXPLAINCLI', () => { it('transformArguments', () => { assert.deepEqual( - EXPLAINCLI.transformArguments('index', '*'), + parseArgs(EXPLAINCLI, 'index', '*'), ['FT.EXPLAINCLI', 'index', '*'] ); }); diff --git a/packages/search/lib/commands/EXPLAINCLI.ts b/packages/search/lib/commands/EXPLAINCLI.ts index e16866991b..7a4ae3a4b2 100644 --- a/packages/search/lib/commands/EXPLAINCLI.ts +++ b/packages/search/lib/commands/EXPLAINCLI.ts @@ -1,10 +1,11 @@ -import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, query: RedisArgument) { - return ['FT.EXPLAINCLI', index, query]; + parseCommand(parser: CommandParser, index: RedisArgument, query: RedisArgument) { + parser.push('FT.EXPLAINCLI', index, query); }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/search/lib/commands/INFO.spec.ts b/packages/search/lib/commands/INFO.spec.ts index e7c7c897a8..cbb4ea9167 100644 --- a/packages/search/lib/commands/INFO.spec.ts +++ b/packages/search/lib/commands/INFO.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INFO, { InfoReply } from './INFO'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('index'), + parseArgs(INFO, 'index'), ['FT.INFO', 'index'] ); }); diff --git a/packages/search/lib/commands/INFO.ts b/packages/search/lib/commands/INFO.ts index 52b87769ce..6792645fe3 100644 --- a/packages/search/lib/commands/INFO.ts +++ b/packages/search/lib/commands/INFO.ts @@ -1,13 +1,14 @@ +import { CommandParser } from '@redis/client/lib/client/parser'; import { RedisArgument } from "@redis/client"; -import { ArrayReply, BlobStringReply, Command, DoubleReply, MapReply, NullReply, NumberReply, ReplyUnion, SimpleStringReply, TypeMapping } from "@redis/client/dist/lib/RESP/types"; -import { createTransformTuplesReplyFunc, transformDoubleReply } from "@redis/client/dist/lib/commands/generic-transformers"; +import { ArrayReply, BlobStringReply, Command, DoubleReply, MapReply, NullReply, NumberReply, ReplyUnion, SimpleStringReply, TypeMapping } from "@redis/client/lib/RESP/types"; +import { createTransformTuplesReplyFunc, transformDoubleReply } from "@redis/client/lib/commands/generic-transformers"; import { TuplesReply } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument) { - return ['FT.INFO', index]; + parseCommand(parser: CommandParser, index: RedisArgument) { + parser.push('FT.INFO', index); }, transformReply: { 2: transformV2Reply, diff --git a/packages/search/lib/commands/PROFILE_AGGREGATE.spec.ts b/packages/search/lib/commands/PROFILE_AGGREGATE.spec.ts index 8644ca5201..ee112118c9 100644 --- a/packages/search/lib/commands/PROFILE_AGGREGATE.spec.ts +++ b/packages/search/lib/commands/PROFILE_AGGREGATE.spec.ts @@ -3,19 +3,20 @@ import testUtils, { GLOBAL } from '../test-utils'; import { FT_AGGREGATE_STEPS } from './AGGREGATE'; import PROFILE_AGGREGATE from './PROFILE_AGGREGATE'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('PROFILE AGGREGATE', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - PROFILE_AGGREGATE.transformArguments('index', 'query'), + parseArgs(PROFILE_AGGREGATE, 'index', 'query'), ['FT.PROFILE', 'index', 'AGGREGATE', 'QUERY', 'query'] ); }); it('with options', () => { assert.deepEqual( - PROFILE_AGGREGATE.transformArguments('index', 'query', { + parseArgs(PROFILE_AGGREGATE, 'index', 'query', { LIMITED: true, VERBATIM: true, STEPS: [{ diff --git a/packages/search/lib/commands/PROFILE_AGGREGATE.ts b/packages/search/lib/commands/PROFILE_AGGREGATE.ts index b6a8db3866..703bfcacc7 100644 --- a/packages/search/lib/commands/PROFILE_AGGREGATE.ts +++ b/packages/search/lib/commands/PROFILE_AGGREGATE.ts @@ -1,27 +1,26 @@ -// import { pushAggregatehOptions, AggregateOptions, transformReply as transformAggregateReply, AggregateRawReply } from './AGGREGATE'; -// import { ProfileOptions, ProfileRawReply, ProfileReply, transformProfile } from '.'; - -import { Command, ReplyUnion } from "@redis/client/dist/lib/RESP/types"; -import AGGREGATE, { AggregateRawReply, FtAggregateOptions, pushAggregateOptions } from "./AGGREGATE"; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ReplyUnion } from "@redis/client/lib/RESP/types"; +import AGGREGATE, { AggregateRawReply, FtAggregateOptions, parseAggregateOptions } from "./AGGREGATE"; import { ProfileOptions, ProfileRawReply, ProfileReply, transformProfile } from "./PROFILE_SEARCH"; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, index: string, query: string, options?: ProfileOptions & FtAggregateOptions ) { - const args = ['FT.PROFILE', index, 'AGGREGATE']; + parser.push('FT.PROFILE', index, 'AGGREGATE'); if (options?.LIMITED) { - args.push('LIMITED'); + parser.push('LIMITED'); } - args.push('QUERY', query); + parser.push('QUERY', query); - return pushAggregateOptions(args, options) + parseAggregateOptions(parser, options) }, transformReply: { 2: (reply: ProfileAggeregateRawReply): ProfileReply => { diff --git a/packages/search/lib/commands/PROFILE_SEARCH.spec.ts b/packages/search/lib/commands/PROFILE_SEARCH.spec.ts index a6e2a968d4..524ff1a522 100644 --- a/packages/search/lib/commands/PROFILE_SEARCH.spec.ts +++ b/packages/search/lib/commands/PROFILE_SEARCH.spec.ts @@ -2,20 +2,21 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import PROFILE_SEARCH from './PROFILE_SEARCH'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('PROFILE SEARCH', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - PROFILE_SEARCH.transformArguments('index', 'query'), + parseArgs(PROFILE_SEARCH, 'index', 'query'), ['FT.PROFILE', 'index', 'SEARCH', 'QUERY', 'query'] ); }); it('with options', () => { assert.deepEqual( - PROFILE_SEARCH.transformArguments('index', 'query', { + parseArgs(PROFILE_SEARCH, 'index', 'query', { LIMITED: true, VERBATIM: true, INKEYS: 'key' diff --git a/packages/search/lib/commands/PROFILE_SEARCH.ts b/packages/search/lib/commands/PROFILE_SEARCH.ts index 5b9e918083..c345e70dd7 100644 --- a/packages/search/lib/commands/PROFILE_SEARCH.ts +++ b/packages/search/lib/commands/PROFILE_SEARCH.ts @@ -1,10 +1,7 @@ -// import { SearchOptions, SearchRawReply, transformReply as transformSearchReply } from './SEARCH'; -// import { pushSearchOptions, ProfileOptions, ProfileRawReply, ProfileReply, transformProfile } from '.'; -// import { RedisCommandArguments } from '@redis/client/dist/lib/commands'; - -import { Command, RedisArgument, ReplyUnion } from "@redis/client/dist/lib/RESP/types"; -import SEARCH, { FtSearchOptions, SearchRawReply, SearchReply, pushSearchOptions } from "./SEARCH"; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, RedisArgument, ReplyUnion } from "@redis/client/lib/RESP/types"; import { AggregateReply } from "./AGGREGATE"; +import SEARCH, { FtSearchOptions, SearchRawReply, SearchReply, parseSearchOptions } from "./SEARCH"; export type ProfileRawReply = [ results: T, @@ -27,22 +24,23 @@ export interface ProfileOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: ProfileOptions & FtSearchOptions ) { - let args: Array = ['FT.PROFILE', index, 'SEARCH']; + parser.push('FT.PROFILE', index, 'SEARCH'); if (options?.LIMITED) { - args.push('LIMITED'); + parser.push('LIMITED'); } - args.push('QUERY', query); + parser.push('QUERY', query); - return pushSearchOptions(args, options); + parseSearchOptions(parser, options); }, transformReply: { 2: (reply: ProfileSearchRawReply, withoutDocuments: boolean): ProfileReply => { diff --git a/packages/search/lib/commands/SEARCH.spec.ts b/packages/search/lib/commands/SEARCH.spec.ts index 257dbb7951..24248b4cf1 100644 --- a/packages/search/lib/commands/SEARCH.spec.ts +++ b/packages/search/lib/commands/SEARCH.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SEARCH from './SEARCH'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SEARCH', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query'), + parseArgs(SEARCH, 'index', 'query'), ['FT.SEARCH', 'index', 'query'] ); }); it('with VERBATIM', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { VERBATIM: true }), ['FT.SEARCH', 'index', 'query', 'VERBATIM'] @@ -22,7 +23,7 @@ describe('FT.SEARCH', () => { it('with NOSTOPWORDS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { NOSTOPWORDS: true }), ['FT.SEARCH', 'index', 'query', 'NOSTOPWORDS'] @@ -31,7 +32,7 @@ describe('FT.SEARCH', () => { it('with INKEYS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { INKEYS: 'key' }), ['FT.SEARCH', 'index', 'query', 'INKEYS', '1', 'key'] @@ -40,7 +41,7 @@ describe('FT.SEARCH', () => { it('with INFIELDS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { INFIELDS: 'field' }), ['FT.SEARCH', 'index', 'query', 'INFIELDS', '1', 'field'] @@ -49,7 +50,7 @@ describe('FT.SEARCH', () => { it('with RETURN', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { RETURN: 'return' }), ['FT.SEARCH', 'index', 'query', 'RETURN', '1', 'return'] @@ -59,7 +60,7 @@ describe('FT.SEARCH', () => { describe('with SUMMARIZE', () => { it('true', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: true }), ['FT.SEARCH', 'index', 'query', 'SUMMARIZE'] @@ -69,7 +70,7 @@ describe('FT.SEARCH', () => { describe('with FIELDS', () => { it('string', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: { FIELDS: '@field' } @@ -80,7 +81,7 @@ describe('FT.SEARCH', () => { it('Array', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: { FIELDS: ['@1', '@2'] } @@ -92,7 +93,7 @@ describe('FT.SEARCH', () => { it('with FRAGS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: { FRAGS: 1 } @@ -103,7 +104,7 @@ describe('FT.SEARCH', () => { it('with LEN', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: { LEN: 1 } @@ -114,7 +115,7 @@ describe('FT.SEARCH', () => { it('with SEPARATOR', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SUMMARIZE: { SEPARATOR: 'separator' } @@ -127,7 +128,7 @@ describe('FT.SEARCH', () => { describe('with HIGHLIGHT', () => { it('true', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { HIGHLIGHT: true }), ['FT.SEARCH', 'index', 'query', 'HIGHLIGHT'] @@ -137,7 +138,7 @@ describe('FT.SEARCH', () => { describe('with FIELDS', () => { it('string', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { HIGHLIGHT: { FIELDS: ['@field'] } @@ -148,7 +149,7 @@ describe('FT.SEARCH', () => { it('Array', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { HIGHLIGHT: { FIELDS: ['@1', '@2'] } @@ -160,7 +161,7 @@ describe('FT.SEARCH', () => { it('with TAGS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { HIGHLIGHT: { TAGS: { open: 'open', @@ -175,7 +176,7 @@ describe('FT.SEARCH', () => { it('with SLOP', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SLOP: 1 }), ['FT.SEARCH', 'index', 'query', 'SLOP', '1'] @@ -184,7 +185,7 @@ describe('FT.SEARCH', () => { it('with TIMEOUT', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { TIMEOUT: 1 }), ['FT.SEARCH', 'index', 'query', 'TIMEOUT', '1'] @@ -193,7 +194,7 @@ describe('FT.SEARCH', () => { it('with INORDER', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { INORDER: true }), ['FT.SEARCH', 'index', 'query', 'INORDER'] @@ -202,7 +203,7 @@ describe('FT.SEARCH', () => { it('with LANGUAGE', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { LANGUAGE: 'Arabic' }), ['FT.SEARCH', 'index', 'query', 'LANGUAGE', 'Arabic'] @@ -211,7 +212,7 @@ describe('FT.SEARCH', () => { it('with EXPANDER', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { EXPANDER: 'expender' }), ['FT.SEARCH', 'index', 'query', 'EXPANDER', 'expender'] @@ -220,7 +221,7 @@ describe('FT.SEARCH', () => { it('with SCORER', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SCORER: 'scorer' }), ['FT.SEARCH', 'index', 'query', 'SCORER', 'scorer'] @@ -229,7 +230,7 @@ describe('FT.SEARCH', () => { it('with SORTBY', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { SORTBY: '@by' }), ['FT.SEARCH', 'index', 'query', 'SORTBY', '@by'] @@ -238,7 +239,7 @@ describe('FT.SEARCH', () => { it('with LIMIT', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { LIMIT: { from: 0, size: 1 @@ -250,7 +251,7 @@ describe('FT.SEARCH', () => { it('with PARAMS', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { PARAMS: { string: 'string', buffer: Buffer.from('buffer'), @@ -263,7 +264,7 @@ describe('FT.SEARCH', () => { it('with DIALECT', () => { assert.deepEqual( - SEARCH.transformArguments('index', 'query', { + parseArgs(SEARCH, 'index', 'query', { DIALECT: 1 }), ['FT.SEARCH', 'index', 'query', 'DIALECT', '1'] diff --git a/packages/search/lib/commands/SEARCH.ts b/packages/search/lib/commands/SEARCH.ts index 1e5e8ec91f..de03ac0070 100644 --- a/packages/search/lib/commands/SEARCH.ts +++ b/packages/search/lib/commands/SEARCH.ts @@ -1,12 +1,15 @@ -import { RedisArgument, Command, ReplyUnion } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushOptionalVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, ReplyUnion } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument, parseOptionalVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { RediSearchProperty, RediSearchLanguage } from './CREATE'; export type FtSearchParams = Record; -export function pushParamsArgument(args: Array, params?: FtSearchParams) { +export function parseParamsArgument(parser: CommandParser, params?: FtSearchParams) { if (params) { - const length = args.push('PARAMS', ''); + parser.push('PARAMS'); + + const args: Array = []; for (const key in params) { if (!Object.hasOwn(params, key)) continue; @@ -17,7 +20,7 @@ export function pushParamsArgument(args: Array, params?: FtSearch ); } - args[length - 1] = (args.length - length).toString(); + parser.pushVariadicWithLength(args); } } @@ -58,109 +61,107 @@ export interface FtSearchOptions { DIALECT?: number; } -export function pushSearchOptions(args: Array, options?: FtSearchOptions) { +export function parseSearchOptions(parser: CommandParser, options?: FtSearchOptions) { if (options?.VERBATIM) { - args.push('VERBATIM'); + parser.push('VERBATIM'); } if (options?.NOSTOPWORDS) { - args.push('NOSTOPWORDS'); + parser.push('NOSTOPWORDS'); } - pushOptionalVariadicArgument(args, 'INKEYS', options?.INKEYS); - pushOptionalVariadicArgument(args, 'INFIELDS', options?.INFIELDS); - pushOptionalVariadicArgument(args, 'RETURN', options?.RETURN); + parseOptionalVariadicArgument(parser, 'INKEYS', options?.INKEYS); + parseOptionalVariadicArgument(parser, 'INFIELDS', options?.INFIELDS); + parseOptionalVariadicArgument(parser, 'RETURN', options?.RETURN); if (options?.SUMMARIZE) { - args.push('SUMMARIZE'); + parser.push('SUMMARIZE'); if (typeof options.SUMMARIZE === 'object') { - pushOptionalVariadicArgument(args, 'FIELDS', options.SUMMARIZE.FIELDS); + parseOptionalVariadicArgument(parser, 'FIELDS', options.SUMMARIZE.FIELDS); if (options.SUMMARIZE.FRAGS !== undefined) { - args.push('FRAGS', options.SUMMARIZE.FRAGS.toString()); + parser.push('FRAGS', options.SUMMARIZE.FRAGS.toString()); } if (options.SUMMARIZE.LEN !== undefined) { - args.push('LEN', options.SUMMARIZE.LEN.toString()); + parser.push('LEN', options.SUMMARIZE.LEN.toString()); } if (options.SUMMARIZE.SEPARATOR !== undefined) { - args.push('SEPARATOR', options.SUMMARIZE.SEPARATOR); + parser.push('SEPARATOR', options.SUMMARIZE.SEPARATOR); } } } if (options?.HIGHLIGHT) { - args.push('HIGHLIGHT'); + parser.push('HIGHLIGHT'); if (typeof options.HIGHLIGHT === 'object') { - pushOptionalVariadicArgument(args, 'FIELDS', options.HIGHLIGHT.FIELDS); + parseOptionalVariadicArgument(parser, 'FIELDS', options.HIGHLIGHT.FIELDS); if (options.HIGHLIGHT.TAGS) { - args.push('TAGS', options.HIGHLIGHT.TAGS.open, options.HIGHLIGHT.TAGS.close); + parser.push('TAGS', options.HIGHLIGHT.TAGS.open, options.HIGHLIGHT.TAGS.close); } } } if (options?.SLOP !== undefined) { - args.push('SLOP', options.SLOP.toString()); + parser.push('SLOP', options.SLOP.toString()); } if (options?.TIMEOUT !== undefined) { - args.push('TIMEOUT', options.TIMEOUT.toString()); + parser.push('TIMEOUT', options.TIMEOUT.toString()); } if (options?.INORDER) { - args.push('INORDER'); + parser.push('INORDER'); } if (options?.LANGUAGE) { - args.push('LANGUAGE', options.LANGUAGE); + parser.push('LANGUAGE', options.LANGUAGE); } if (options?.EXPANDER) { - args.push('EXPANDER', options.EXPANDER); + parser.push('EXPANDER', options.EXPANDER); } if (options?.SCORER) { - args.push('SCORER', options.SCORER); + parser.push('SCORER', options.SCORER); } if (options?.SORTBY) { - args.push('SORTBY'); + parser.push('SORTBY'); if (typeof options.SORTBY === 'string' || options.SORTBY instanceof Buffer) { - args.push(options.SORTBY); + parser.push(options.SORTBY); } else { - args.push(options.SORTBY.BY); + parser.push(options.SORTBY.BY); if (options.SORTBY.DIRECTION) { - args.push(options.SORTBY.DIRECTION); + parser.push(options.SORTBY.DIRECTION); } } } if (options?.LIMIT) { - args.push('LIMIT', options.LIMIT.from.toString(), options.LIMIT.size.toString()); + parser.push('LIMIT', options.LIMIT.from.toString(), options.LIMIT.size.toString()); } - pushParamsArgument(args, options?.PARAMS); + parseParamsArgument(parser, options?.PARAMS); if (options?.DIALECT !== undefined) { - args.push('DIALECT', options.DIALECT.toString()); + parser.push('DIALECT', options.DIALECT.toString()); } - - return args; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, query: RedisArgument, options?: FtSearchOptions) { - const args = ['FT.SEARCH', index, query]; + parseCommand(parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: FtSearchOptions) { + parser.push('FT.SEARCH', index, query); - return pushSearchOptions(args, options); + parseSearchOptions(parser, options); }, transformReply: { 2: (reply: SearchRawReply): SearchReply => { diff --git a/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts b/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts index be998b9e63..bfcca8b4bd 100644 --- a/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts +++ b/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts @@ -1,12 +1,13 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; import SEARCH_NOCONTENT from './SEARCH_NOCONTENT'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SEARCH NOCONTENT', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - SEARCH_NOCONTENT.transformArguments('index', 'query'), + parseArgs(SEARCH_NOCONTENT, 'index', 'query'), ['FT.SEARCH', 'index', 'query', 'NOCONTENT'] ); }); diff --git a/packages/search/lib/commands/SEARCH_NOCONTENT.ts b/packages/search/lib/commands/SEARCH_NOCONTENT.ts index 4ee959b9d7..a4c6f6a27a 100644 --- a/packages/search/lib/commands/SEARCH_NOCONTENT.ts +++ b/packages/search/lib/commands/SEARCH_NOCONTENT.ts @@ -1,13 +1,12 @@ -import { Command, ReplyUnion } from '@redis/client/dist/lib/RESP/types'; +import { Command, ReplyUnion } from '@redis/client/lib/RESP/types'; import SEARCH, { SearchRawReply } from './SEARCH'; export default { - FIRST_KEY_INDEX: SEARCH.FIRST_KEY_INDEX, + NOT_KEYED_COMMAND: SEARCH.NOT_KEYED_COMMAND, IS_READ_ONLY: SEARCH.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const redisArgs = SEARCH.transformArguments(...args); - redisArgs.push('NOCONTENT'); - return redisArgs; + parseCommand(...args: Parameters) { + SEARCH.parseCommand(...args); + args[0].push('NOCONTENT'); }, transformReply: { 2: (reply: SearchRawReply): SearchNoContentReply => { diff --git a/packages/search/lib/commands/SPELLCHECK.spec.ts b/packages/search/lib/commands/SPELLCHECK.spec.ts index a70ee96492..4f5a3628f4 100644 --- a/packages/search/lib/commands/SPELLCHECK.spec.ts +++ b/packages/search/lib/commands/SPELLCHECK.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SPELLCHECK from './SPELLCHECK'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SPELLCHECK', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - SPELLCHECK.transformArguments('index', 'query'), + parseArgs(SPELLCHECK, 'index', 'query'), ['FT.SPELLCHECK', 'index', 'query'] ); }); it('with DISTANCE', () => { assert.deepEqual( - SPELLCHECK.transformArguments('index', 'query', { + parseArgs(SPELLCHECK, 'index', 'query', { DISTANCE: 2 }), ['FT.SPELLCHECK', 'index', 'query', 'DISTANCE', '2'] @@ -23,7 +24,7 @@ describe('FT.SPELLCHECK', () => { describe('with TERMS', () => { it('single', () => { assert.deepEqual( - SPELLCHECK.transformArguments('index', 'query', { + parseArgs(SPELLCHECK, 'index', 'query', { TERMS: { mode: 'INCLUDE', dictionary: 'dictionary' @@ -35,7 +36,7 @@ describe('FT.SPELLCHECK', () => { it('multiple', () => { assert.deepEqual( - SPELLCHECK.transformArguments('index', 'query', { + parseArgs(SPELLCHECK, 'index', 'query', { TERMS: [{ mode: 'INCLUDE', dictionary: 'include' @@ -51,7 +52,7 @@ describe('FT.SPELLCHECK', () => { it('with DIALECT', () => { assert.deepEqual( - SPELLCHECK.transformArguments('index', 'query', { + parseArgs(SPELLCHECK, 'index', 'query', { DIALECT: 1 }), ['FT.SPELLCHECK', 'index', 'query', 'DIALECT', '1'] diff --git a/packages/search/lib/commands/SPELLCHECK.ts b/packages/search/lib/commands/SPELLCHECK.ts index f52e74ba0f..1e6981d01f 100644 --- a/packages/search/lib/commands/SPELLCHECK.ts +++ b/packages/search/lib/commands/SPELLCHECK.ts @@ -1,4 +1,5 @@ -import { RedisArgument, CommandArguments, Command, ReplyUnion } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command, ReplyUnion } from '@redis/client/lib/RESP/types'; export interface Terms { mode: 'INCLUDE' | 'EXCLUDE'; @@ -12,30 +13,28 @@ export interface FtSpellCheckOptions { } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, query: RedisArgument, options?: FtSpellCheckOptions) { - const args = ['FT.SPELLCHECK', index, query]; + parseCommand(parser: CommandParser, index: RedisArgument, query: RedisArgument, options?: FtSpellCheckOptions) { + parser.push('FT.SPELLCHECK', index, query); if (options?.DISTANCE) { - args.push('DISTANCE', options.DISTANCE.toString()); + parser.push('DISTANCE', options.DISTANCE.toString()); } if (options?.TERMS) { if (Array.isArray(options.TERMS)) { for (const term of options.TERMS) { - pushTerms(args, term); + parseTerms(parser, term); } } else { - pushTerms(args, options.TERMS); + parseTerms(parser, options.TERMS); } } if (options?.DIALECT) { - args.push('DIALECT', options.DIALECT.toString()); + parser.push('DIALECT', options.DIALECT.toString()); } - - return args; }, transformReply: { 2: (rawReply: SpellCheckRawReply): SpellCheckReply => { @@ -52,6 +51,10 @@ export default { unstableResp3: true } as const satisfies Command; +function parseTerms(parser: CommandParser, { mode, dictionary }: Terms) { + parser.push('TERMS', mode, dictionary); +} + type SpellCheckRawReply = Array<[ _: string, term: string, @@ -65,7 +68,3 @@ type SpellCheckReply = Array<{ suggestion: string }> }>; - -function pushTerms(args: CommandArguments, { mode, dictionary }: Terms) { - args.push('TERMS', mode, dictionary); -} diff --git a/packages/search/lib/commands/SUGADD.spec.ts b/packages/search/lib/commands/SUGADD.spec.ts index 24e03d3779..2e0ce92edb 100644 --- a/packages/search/lib/commands/SUGADD.spec.ts +++ b/packages/search/lib/commands/SUGADD.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGADD from './SUGADD'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGADD', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - SUGADD.transformArguments('key', 'string', 1), + parseArgs(SUGADD, 'key', 'string', 1), ['FT.SUGADD', 'key', 'string', '1'] ); }); it('with INCR', () => { assert.deepEqual( - SUGADD.transformArguments('key', 'string', 1, { INCR: true }), + parseArgs(SUGADD, 'key', 'string', 1, { INCR: true }), ['FT.SUGADD', 'key', 'string', '1', 'INCR'] ); }); it('with PAYLOAD', () => { assert.deepEqual( - SUGADD.transformArguments('key', 'string', 1, { PAYLOAD: 'payload' }), + parseArgs(SUGADD, 'key', 'string', 1, { PAYLOAD: 'payload' }), ['FT.SUGADD', 'key', 'string', '1', 'PAYLOAD', 'payload'] ); }); diff --git a/packages/search/lib/commands/SUGADD.ts b/packages/search/lib/commands/SUGADD.ts index c18cd7846e..a82f03ffa1 100644 --- a/packages/search/lib/commands/SUGADD.ts +++ b/packages/search/lib/commands/SUGADD.ts @@ -1,4 +1,5 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export interface FtSugAddOptions { INCR?: boolean; @@ -6,20 +7,19 @@ export interface FtSugAddOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, string: RedisArgument, score: number, options?: FtSugAddOptions) { - const args = ['FT.SUGADD', key, string, score.toString()]; + parseCommand(parser: CommandParser, key: RedisArgument, string: RedisArgument, score: number, options?: FtSugAddOptions) { + parser.push('FT.SUGADD'); + parser.pushKey(key); + parser.push(string, score.toString()); if (options?.INCR) { - args.push('INCR'); + parser.push('INCR'); } if (options?.PAYLOAD) { - args.push('PAYLOAD', options.PAYLOAD); + parser.push('PAYLOAD', options.PAYLOAD); } - - return args; }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/search/lib/commands/SUGDEL.spec.ts b/packages/search/lib/commands/SUGDEL.spec.ts index ea92c2a1a4..21677f1421 100644 --- a/packages/search/lib/commands/SUGDEL.spec.ts +++ b/packages/search/lib/commands/SUGDEL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGDEL from './SUGDEL'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGDEL', () => { it('transformArguments', () => { assert.deepEqual( - SUGDEL.transformArguments('key', 'string'), + parseArgs(SUGDEL, 'key', 'string'), ['FT.SUGDEL', 'key', 'string'] ); }); diff --git a/packages/search/lib/commands/SUGDEL.ts b/packages/search/lib/commands/SUGDEL.ts index 5829ec40a2..1cdf56d202 100644 --- a/packages/search/lib/commands/SUGDEL.ts +++ b/packages/search/lib/commands/SUGDEL.ts @@ -1,10 +1,12 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, string: RedisArgument) { - return ['FT.SUGDEL', key, string]; + parseCommand(parser: CommandParser, key: RedisArgument, string: RedisArgument) { + parser.push('FT.SUGDEL'); + parser.pushKey(key); + parser.push(string); }, transformReply: undefined as unknown as () => NumberReply<0 | 1> } as const satisfies Command; diff --git a/packages/search/lib/commands/SUGGET.spec.ts b/packages/search/lib/commands/SUGGET.spec.ts index 6ea4c03f32..e30c62afd6 100644 --- a/packages/search/lib/commands/SUGGET.spec.ts +++ b/packages/search/lib/commands/SUGGET.spec.ts @@ -1,26 +1,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGGET from './SUGGET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGGET', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - SUGGET.transformArguments('key', 'prefix'), + parseArgs(SUGGET, 'key', 'prefix'), ['FT.SUGGET', 'key', 'prefix'] ); }); it('with FUZZY', () => { assert.deepEqual( - SUGGET.transformArguments('key', 'prefix', { FUZZY: true }), + parseArgs(SUGGET, 'key', 'prefix', { FUZZY: true }), ['FT.SUGGET', 'key', 'prefix', 'FUZZY'] ); }); it('with MAX', () => { assert.deepEqual( - SUGGET.transformArguments('key', 'prefix', { MAX: 10 }), + parseArgs(SUGGET, 'key', 'prefix', { MAX: 10 }), ['FT.SUGGET', 'key', 'prefix', 'MAX', '10'] ); }); diff --git a/packages/search/lib/commands/SUGGET.ts b/packages/search/lib/commands/SUGGET.ts index 53dc57a86a..607e26df94 100644 --- a/packages/search/lib/commands/SUGGET.ts +++ b/packages/search/lib/commands/SUGGET.ts @@ -1,4 +1,5 @@ -import { NullReply, ArrayReply, BlobStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { NullReply, ArrayReply, BlobStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; export interface FtSugGetOptions { FUZZY?: boolean; @@ -6,20 +7,19 @@ export interface FtSugGetOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, prefix: RedisArgument, options?: FtSugGetOptions) { - const args = ['FT.SUGGET', key, prefix]; + parseCommand(parser: CommandParser, key: RedisArgument, prefix: RedisArgument, options?: FtSugGetOptions) { + parser.push('FT.SUGGET'); + parser.pushKey(key); + parser.push(prefix); if (options?.FUZZY) { - args.push('FUZZY'); + parser.push('FUZZY'); } if (options?.MAX !== undefined) { - args.push('MAX', options.MAX.toString()); + parser.push('MAX', options.MAX.toString()); } - - return args; }, transformReply: undefined as unknown as () => NullReply | ArrayReply } as const satisfies Command; diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts index 42a427ce1f..160d7e3eb7 100644 --- a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGGET_WITHPAYLOADS from './SUGGET_WITHPAYLOADS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGGET WITHPAYLOADS', () => { it('transformArguments', () => { assert.deepEqual( - SUGGET_WITHPAYLOADS.transformArguments('key', 'prefix'), + parseArgs(SUGGET_WITHPAYLOADS, 'key', 'prefix'), ['FT.SUGGET', 'key', 'prefix', 'WITHPAYLOADS'] ); }); diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts index d8b097f3db..b2112bb4b3 100644 --- a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts +++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts @@ -1,14 +1,12 @@ -import { NullReply, ArrayReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { isNullReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { NullReply, ArrayReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; +import { isNullReply } from '@redis/client/lib/commands/generic-transformers'; import SUGGET from './SUGGET'; export default { - FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, IS_READ_ONLY: SUGGET.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const transformedArguments = SUGGET.transformArguments(...args); - transformedArguments.push('WITHPAYLOADS'); - return transformedArguments; + parseCommand(...args: Parameters) { + SUGGET.parseCommand(...args); + args[0].push('WITHPAYLOADS'); }, transformReply(reply: NullReply | UnwrapReply>) { if (isNullReply(reply)) return null; diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts index 6969be7729..262defb793 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGGET_WITHSCORES from './SUGGET_WITHSCORES'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGGET WITHSCORES', () => { it('transformArguments', () => { assert.deepEqual( - SUGGET_WITHSCORES.transformArguments('key', 'prefix'), + parseArgs(SUGGET_WITHSCORES, 'key', 'prefix'), ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES'] ); }); diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.ts index 9d24d95cbb..088153c31f 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES.ts @@ -1,5 +1,5 @@ -import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '@redis/client/dist/lib/RESP/types'; -import { isNullReply, transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '@redis/client/lib/RESP/types'; +import { isNullReply, transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; import SUGGET from './SUGGET'; type SuggestScore = { @@ -8,12 +8,10 @@ type SuggestScore = { } export default { - FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, IS_READ_ONLY: SUGGET.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const transformedArguments = SUGGET.transformArguments(...args); - transformedArguments.push('WITHSCORES'); - return transformedArguments; + parseCommand(...args: Parameters) { + SUGGET.parseCommand(...args); + args[0].push('WITHSCORES'); }, transformReply: { 2: (reply: NullReply | UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts index 98aad1c802..573708f689 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGGET_WITHSCORES_WITHPAYLOADS from './SUGGET_WITHSCORES_WITHPAYLOADS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGGET WITHSCORES WITHPAYLOADS', () => { it('transformArguments', () => { assert.deepEqual( - SUGGET_WITHSCORES_WITHPAYLOADS.transformArguments('key', 'prefix'), + parseArgs(SUGGET_WITHSCORES_WITHPAYLOADS, 'key', 'prefix'), ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES', 'WITHPAYLOADS'] ); }); diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts index 1e125eb15f..6f032a1589 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts @@ -1,5 +1,5 @@ -import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '@redis/client/dist/lib/RESP/types'; -import { isNullReply, transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '@redis/client/lib/RESP/types'; +import { isNullReply, transformDoubleReply } from '@redis/client/lib/commands/generic-transformers'; import SUGGET from './SUGGET'; type SuggestScoreWithPayload = { @@ -9,15 +9,13 @@ type SuggestScoreWithPayload = { } export default { - FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, IS_READ_ONLY: SUGGET.IS_READ_ONLY, - transformArguments(...args: Parameters) { - const transformedArguments = SUGGET.transformArguments(...args); - transformedArguments.push( + parseCommand(...args: Parameters) { + SUGGET.parseCommand(...args); + args[0].push( 'WITHSCORES', 'WITHPAYLOADS' ); - return transformedArguments; }, transformReply: { 2: (reply: NullReply | UnwrapReply>, preserve?: any, typeMapping?: TypeMapping) => { diff --git a/packages/search/lib/commands/SUGLEN.spec.ts b/packages/search/lib/commands/SUGLEN.spec.ts index 6e6d5e1fc5..d738f09042 100644 --- a/packages/search/lib/commands/SUGLEN.spec.ts +++ b/packages/search/lib/commands/SUGLEN.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SUGLEN from './SUGLEN'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SUGLEN', () => { it('transformArguments', () => { assert.deepEqual( - SUGLEN.transformArguments('key'), + parseArgs(SUGLEN, 'key'), ['FT.SUGLEN', 'key'] ); }); diff --git a/packages/search/lib/commands/SUGLEN.ts b/packages/search/lib/commands/SUGLEN.ts index 85dde8cfb7..7437559843 100644 --- a/packages/search/lib/commands/SUGLEN.ts +++ b/packages/search/lib/commands/SUGLEN.ts @@ -1,10 +1,10 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument) { - return ['FT.SUGLEN', key]; + parseCommand(parser: CommandParser, key: RedisArgument) { + parser.push('FT.SUGLEN', key); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/search/lib/commands/SYNDUMP.spec.ts b/packages/search/lib/commands/SYNDUMP.spec.ts index 59c010a8d6..88bf50cfb5 100644 --- a/packages/search/lib/commands/SYNDUMP.spec.ts +++ b/packages/search/lib/commands/SYNDUMP.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SYNDUMP from './SYNDUMP'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SYNDUMP', () => { it('transformArguments', () => { assert.deepEqual( - SYNDUMP.transformArguments('index'), + parseArgs(SYNDUMP, 'index'), ['FT.SYNDUMP', 'index'] ); }); diff --git a/packages/search/lib/commands/SYNDUMP.ts b/packages/search/lib/commands/SYNDUMP.ts index 2fe7540fda..0c3b68bf2e 100644 --- a/packages/search/lib/commands/SYNDUMP.ts +++ b/packages/search/lib/commands/SYNDUMP.ts @@ -1,10 +1,11 @@ -import { RedisArgument, MapReply, BlobStringReply, ArrayReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, MapReply, BlobStringReply, ArrayReply, UnwrapReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument) { - return ['FT.SYNDUMP', index]; + parseCommand(parser: CommandParser, index: RedisArgument) { + parser.push('FT.SYNDUMP', index); }, transformReply: { 2: (reply: UnwrapReply>>) => { diff --git a/packages/search/lib/commands/SYNUPDATE.spec.ts b/packages/search/lib/commands/SYNUPDATE.spec.ts index e901ae9fe3..f93e059915 100644 --- a/packages/search/lib/commands/SYNUPDATE.spec.ts +++ b/packages/search/lib/commands/SYNUPDATE.spec.ts @@ -2,26 +2,27 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import SYNUPDATE from './SYNUPDATE'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.SYNUPDATE', () => { describe('transformArguments', () => { it('single term', () => { assert.deepEqual( - SYNUPDATE.transformArguments('index', 'groupId', 'term'), + parseArgs(SYNUPDATE, 'index', 'groupId', 'term'), ['FT.SYNUPDATE', 'index', 'groupId', 'term'] ); }); it('multiple terms', () => { assert.deepEqual( - SYNUPDATE.transformArguments('index', 'groupId', ['1', '2']), + parseArgs(SYNUPDATE, 'index', 'groupId', ['1', '2']), ['FT.SYNUPDATE', 'index', 'groupId', '1', '2'] ); }); it('with SKIPINITIALSCAN', () => { assert.deepEqual( - SYNUPDATE.transformArguments('index', 'groupId', 'term', { + parseArgs(SYNUPDATE, 'index', 'groupId', 'term', { SKIPINITIALSCAN: true }), ['FT.SYNUPDATE', 'index', 'groupId', 'SKIPINITIALSCAN', 'term'] diff --git a/packages/search/lib/commands/SYNUPDATE.ts b/packages/search/lib/commands/SYNUPDATE.ts index 926d8e58e1..2baf2ded18 100644 --- a/packages/search/lib/commands/SYNUPDATE.ts +++ b/packages/search/lib/commands/SYNUPDATE.ts @@ -1,26 +1,28 @@ -import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { SimpleStringReply, Command, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export interface FtSynUpdateOptions { SKIPINITIALSCAN?: boolean; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments( + parseCommand( + parser: CommandParser, index: RedisArgument, groupId: RedisArgument, terms: RedisVariadicArgument, options?: FtSynUpdateOptions ) { - const args = ['FT.SYNUPDATE', index, groupId]; + parser.push('FT.SYNUPDATE', index, groupId); if (options?.SKIPINITIALSCAN) { - args.push('SKIPINITIALSCAN'); + parser.push('SKIPINITIALSCAN'); } - return pushVariadicArguments(args, terms); + parser.pushVariadic(terms); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/search/lib/commands/TAGVALS.spec.ts b/packages/search/lib/commands/TAGVALS.spec.ts index dbc6203f93..f0d83c9f7a 100644 --- a/packages/search/lib/commands/TAGVALS.spec.ts +++ b/packages/search/lib/commands/TAGVALS.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import TAGVALS from './TAGVALS'; import { SCHEMA_FIELD_TYPE } from './CREATE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('FT.TAGVALS', () => { it('transformArguments', () => { assert.deepEqual( - TAGVALS.transformArguments('index', '@field'), + parseArgs(TAGVALS, 'index', '@field'), ['FT.TAGVALS', 'index', '@field'] ); }); diff --git a/packages/search/lib/commands/TAGVALS.ts b/packages/search/lib/commands/TAGVALS.ts index 8a6e73c97b..d00d657f3a 100644 --- a/packages/search/lib/commands/TAGVALS.ts +++ b/packages/search/lib/commands/TAGVALS.ts @@ -1,10 +1,11 @@ -import { RedisArgument, ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(index: RedisArgument, fieldName: RedisArgument) { - return ['FT.TAGVALS', index, fieldName]; + parseCommand(parser: CommandParser, index: RedisArgument, fieldName: RedisArgument) { + parser.push('FT.TAGVALS', index, fieldName); }, transformReply: { 2: undefined as unknown as () => ArrayReply, diff --git a/packages/search/lib/commands/_LIST.spec.ts b/packages/search/lib/commands/_LIST.spec.ts index a7f13b011a..dfe32f2e29 100644 --- a/packages/search/lib/commands/_LIST.spec.ts +++ b/packages/search/lib/commands/_LIST.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import _LIST from './_LIST'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('_LIST', () => { it('transformArguments', () => { assert.deepEqual( - _LIST.transformArguments(), + parseArgs(_LIST), ['FT._LIST'] ); }); diff --git a/packages/search/lib/commands/_LIST.ts b/packages/search/lib/commands/_LIST.ts index efb6c31acc..432eea6479 100644 --- a/packages/search/lib/commands/_LIST.ts +++ b/packages/search/lib/commands/_LIST.ts @@ -1,10 +1,11 @@ -import { ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { ArrayReply, SetReply, BlobStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments() { - return ['FT._LIST']; + parseCommand(parser: CommandParser) { + parser.push('FT._LIST'); }, transformReply: { 2: undefined as unknown as () => ArrayReply, diff --git a/packages/test-utils/lib/dockers.ts b/packages/test-utils/lib/dockers.ts index a1cb63eb7b..e8d7ad45ca 100644 --- a/packages/test-utils/lib/dockers.ts +++ b/packages/test-utils/lib/dockers.ts @@ -2,7 +2,7 @@ import { createConnection } from 'node:net'; import { once } from 'node:events'; import { createClient } from '@redis/client/index'; import { setTimeout } from 'node:timers/promises'; -// import { ClusterSlotsReply } from '@redis/client/dist/lib/commands/CLUSTER_SLOTS'; +// import { ClusterSlotsReply } from '@redis/client/lib/commands/CLUSTER_SLOTS'; import { promisify } from 'node:util'; import { exec } from 'node:child_process'; const execAsync = promisify(exec); diff --git a/packages/time-series/lib/commands/ADD.spec.ts b/packages/time-series/lib/commands/ADD.spec.ts index 7dcf031c2b..055d2246d8 100644 --- a/packages/time-series/lib/commands/ADD.spec.ts +++ b/packages/time-series/lib/commands/ADD.spec.ts @@ -2,19 +2,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ADD from './ADD'; import { TIME_SERIES_ENCODING, TIME_SERIES_DUPLICATE_POLICIES } from '.'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.ADD', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1), + parseArgs(ADD, 'key', '*', 1), ['TS.ADD', 'key', '*', '1'] ); }); it('with RETENTION', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { RETENTION: 1 }), ['TS.ADD', 'key', '*', '1', 'RETENTION', '1'] @@ -23,7 +24,7 @@ describe('TS.ADD', () => { it('with ENCODING', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED }), ['TS.ADD', 'key', '*', '1', 'ENCODING', 'UNCOMPRESSED'] @@ -32,7 +33,7 @@ describe('TS.ADD', () => { it('with CHUNK_SIZE', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { CHUNK_SIZE: 1 }), ['TS.ADD', 'key', '*', '1', 'CHUNK_SIZE', '1'] @@ -41,7 +42,7 @@ describe('TS.ADD', () => { it('with ON_DUPLICATE', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { ON_DUPLICATE: TIME_SERIES_DUPLICATE_POLICIES.BLOCK }), ['TS.ADD', 'key', '*', '1', 'ON_DUPLICATE', 'BLOCK'] @@ -50,7 +51,7 @@ describe('TS.ADD', () => { it('with LABELS', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { LABELS: { label: 'value' } }), ['TS.ADD', 'key', '*', '1', 'LABELS', 'label', 'value'] @@ -59,7 +60,7 @@ describe('TS.ADD', () => { it ('with IGNORE', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { IGNORE: { maxTimeDiff: 1, maxValDiff: 1 @@ -71,7 +72,7 @@ describe('TS.ADD', () => { it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS, IGNORE', () => { assert.deepEqual( - ADD.transformArguments('key', '*', 1, { + parseArgs(ADD, 'key', '*', 1, { RETENTION: 1, ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED, CHUNK_SIZE: 1, diff --git a/packages/time-series/lib/commands/ADD.ts b/packages/time-series/lib/commands/ADD.ts index 1842dcfc34..f79a27c5db 100644 --- a/packages/time-series/lib/commands/ADD.ts +++ b/packages/time-series/lib/commands/ADD.ts @@ -1,15 +1,16 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; import { transformTimestampArgument, - pushRetentionArgument, + parseRetentionArgument, TimeSeriesEncoding, - pushEncodingArgument, - pushChunkSizeArgument, + parseEncodingArgument, + parseChunkSizeArgument, TimeSeriesDuplicatePolicies, Labels, - pushLabelsArgument, + parseLabelsArgument, Timestamp, - pushIgnoreArgument + parseIgnoreArgument } from '.'; export interface TsIgnoreOptions { @@ -27,36 +28,31 @@ export interface TsAddOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, key: RedisArgument, timestamp: Timestamp, value: number, options?: TsAddOptions ) { - const args = [ - 'TS.ADD', - key, - transformTimestampArgument(timestamp), - value.toString() - ]; + parser.push('TS.ADD'); + parser.pushKey(key); + parser.push(transformTimestampArgument(timestamp), value.toString()); - pushRetentionArgument(args, options?.RETENTION); + parseRetentionArgument(parser, options?.RETENTION); - pushEncodingArgument(args, options?.ENCODING); + parseEncodingArgument(parser, options?.ENCODING); - pushChunkSizeArgument(args, options?.CHUNK_SIZE); + parseChunkSizeArgument(parser, options?.CHUNK_SIZE); if (options?.ON_DUPLICATE) { - args.push('ON_DUPLICATE', options.ON_DUPLICATE); + parser.push('ON_DUPLICATE', options.ON_DUPLICATE); } - pushLabelsArgument(args, options?.LABELS); + parseLabelsArgument(parser, options?.LABELS); - pushIgnoreArgument(args, options?.IGNORE); - - return args; + parseIgnoreArgument(parser, options?.IGNORE); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/ALTER.spec.ts b/packages/time-series/lib/commands/ALTER.spec.ts index 1b24111156..560d9ffde2 100644 --- a/packages/time-series/lib/commands/ALTER.spec.ts +++ b/packages/time-series/lib/commands/ALTER.spec.ts @@ -2,19 +2,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import ALTER from './ALTER'; import { TIME_SERIES_DUPLICATE_POLICIES } from '.'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.ALTER', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - ALTER.transformArguments('key'), + parseArgs(ALTER, 'key'), ['TS.ALTER', 'key'] ); }); it('with RETENTION', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { RETENTION: 1 }), ['TS.ALTER', 'key', 'RETENTION', '1'] @@ -23,7 +24,7 @@ describe('TS.ALTER', () => { it('with CHUNK_SIZE', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { CHUNK_SIZE: 1 }), ['TS.ALTER', 'key', 'CHUNK_SIZE', '1'] @@ -32,7 +33,7 @@ describe('TS.ALTER', () => { it('with DUPLICATE_POLICY', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK }), ['TS.ALTER', 'key', 'DUPLICATE_POLICY', 'BLOCK'] @@ -41,7 +42,7 @@ describe('TS.ALTER', () => { it('with LABELS', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { LABELS: { label: 'value' } }), ['TS.ALTER', 'key', 'LABELS', 'label', 'value'] @@ -50,7 +51,7 @@ describe('TS.ALTER', () => { it('with IGNORE with MAX_TIME_DIFF', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { IGNORE: { maxTimeDiff: 1, maxValDiff: 1 @@ -62,7 +63,7 @@ describe('TS.ALTER', () => { it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( - ALTER.transformArguments('key', { + parseArgs(ALTER, 'key', { RETENTION: 1, CHUNK_SIZE: 1, DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK, diff --git a/packages/time-series/lib/commands/ALTER.ts b/packages/time-series/lib/commands/ALTER.ts index f77edb5c43..8217e81c21 100644 --- a/packages/time-series/lib/commands/ALTER.ts +++ b/packages/time-series/lib/commands/ALTER.ts @@ -1,26 +1,25 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; import { TsCreateOptions } from './CREATE'; -import { pushRetentionArgument, pushChunkSizeArgument, pushDuplicatePolicy, pushLabelsArgument, pushIgnoreArgument } from '.'; +import { parseRetentionArgument, parseChunkSizeArgument, parseDuplicatePolicy, parseLabelsArgument, parseIgnoreArgument } from '.'; export type TsAlterOptions = Pick; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: TsAlterOptions) { - const args = ['TS.ALTER', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: TsAlterOptions) { + parser.push('TS.ALTER'); + parser.pushKey(key); - pushRetentionArgument(args, options?.RETENTION); + parseRetentionArgument(parser, options?.RETENTION); - pushChunkSizeArgument(args, options?.CHUNK_SIZE); + parseChunkSizeArgument(parser, options?.CHUNK_SIZE); - pushDuplicatePolicy(args, options?.DUPLICATE_POLICY); + parseDuplicatePolicy(parser, options?.DUPLICATE_POLICY); - pushLabelsArgument(args, options?.LABELS); + parseLabelsArgument(parser, options?.LABELS); - pushIgnoreArgument(args, options?.IGNORE); - - return args; + parseIgnoreArgument(parser, options?.IGNORE); }, -transformReply: undefined as unknown as () => SimpleStringReply<'OK'> + transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/time-series/lib/commands/CREATE.spec.ts b/packages/time-series/lib/commands/CREATE.spec.ts index feff9cbdd7..795b59b880 100644 --- a/packages/time-series/lib/commands/CREATE.spec.ts +++ b/packages/time-series/lib/commands/CREATE.spec.ts @@ -2,19 +2,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CREATE from './CREATE'; import { TIME_SERIES_ENCODING, TIME_SERIES_DUPLICATE_POLICIES } from '.'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.CREATE', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - CREATE.transformArguments('key'), + parseArgs(CREATE, 'key'), ['TS.CREATE', 'key'] ); }); it('with RETENTION', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { RETENTION: 1 }), ['TS.CREATE', 'key', 'RETENTION', '1'] @@ -23,7 +24,7 @@ describe('TS.CREATE', () => { it('with ENCODING', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED }), ['TS.CREATE', 'key', 'ENCODING', 'UNCOMPRESSED'] @@ -32,7 +33,7 @@ describe('TS.CREATE', () => { it('with CHUNK_SIZE', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { CHUNK_SIZE: 1 }), ['TS.CREATE', 'key', 'CHUNK_SIZE', '1'] @@ -41,7 +42,7 @@ describe('TS.CREATE', () => { it('with DUPLICATE_POLICY', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK }), ['TS.CREATE', 'key', 'DUPLICATE_POLICY', 'BLOCK'] @@ -50,7 +51,7 @@ describe('TS.CREATE', () => { it('with LABELS', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { LABELS: { label: 'value' } }), ['TS.CREATE', 'key', 'LABELS', 'label', 'value'] @@ -59,7 +60,7 @@ describe('TS.CREATE', () => { it('with IGNORE with MAX_TIME_DIFF', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { IGNORE: { maxTimeDiff: 1, maxValDiff: 1 @@ -71,7 +72,7 @@ describe('TS.CREATE', () => { it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( - CREATE.transformArguments('key', { + parseArgs(CREATE, 'key', { RETENTION: 1, ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED, CHUNK_SIZE: 1, diff --git a/packages/time-series/lib/commands/CREATE.ts b/packages/time-series/lib/commands/CREATE.ts index abb84de12a..86defd1e0a 100644 --- a/packages/time-series/lib/commands/CREATE.ts +++ b/packages/time-series/lib/commands/CREATE.ts @@ -1,14 +1,15 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; import { - pushRetentionArgument, + parseRetentionArgument, TimeSeriesEncoding, - pushEncodingArgument, - pushChunkSizeArgument, + parseEncodingArgument, + parseChunkSizeArgument, TimeSeriesDuplicatePolicies, - pushDuplicatePolicy, + parseDuplicatePolicy, Labels, - pushLabelsArgument, - pushIgnoreArgument + parseLabelsArgument, + parseIgnoreArgument } from '.'; import { TsIgnoreOptions } from './ADD'; @@ -22,24 +23,22 @@ export interface TsCreateOptions { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, options?: TsCreateOptions) { - const args = ['TS.CREATE', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: TsCreateOptions) { + parser.push('TS.CREATE'); + parser.pushKey(key); - pushRetentionArgument(args, options?.RETENTION); + parseRetentionArgument(parser, options?.RETENTION); - pushEncodingArgument(args, options?.ENCODING); + parseEncodingArgument(parser, options?.ENCODING); - pushChunkSizeArgument(args, options?.CHUNK_SIZE); + parseChunkSizeArgument(parser, options?.CHUNK_SIZE); - pushDuplicatePolicy(args, options?.DUPLICATE_POLICY); + parseDuplicatePolicy(parser, options?.DUPLICATE_POLICY); - pushLabelsArgument(args, options?.LABELS); + parseLabelsArgument(parser, options?.LABELS); - pushIgnoreArgument(args, options?.IGNORE); - - return args; + parseIgnoreArgument(parser, options?.IGNORE); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/time-series/lib/commands/CREATERULE.spec.ts b/packages/time-series/lib/commands/CREATERULE.spec.ts index f1e5b93450..da26bf458e 100644 --- a/packages/time-series/lib/commands/CREATERULE.spec.ts +++ b/packages/time-series/lib/commands/CREATERULE.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import CREATERULE, { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.CREATERULE', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - CREATERULE.transformArguments('source', 'destination', TIME_SERIES_AGGREGATION_TYPE.AVG, 1), + parseArgs(CREATERULE, 'source', 'destination', TIME_SERIES_AGGREGATION_TYPE.AVG, 1), ['TS.CREATERULE', 'source', 'destination', 'AGGREGATION', 'AVG', '1'] ); }); it('with alignTimestamp', () => { assert.deepEqual( - CREATERULE.transformArguments('source', 'destination', TIME_SERIES_AGGREGATION_TYPE.AVG, 1, 1), + parseArgs(CREATERULE, 'source', 'destination', TIME_SERIES_AGGREGATION_TYPE.AVG, 1, 1), ['TS.CREATERULE', 'source', 'destination', 'AGGREGATION', 'AVG', '1', '1'] ); }); diff --git a/packages/time-series/lib/commands/CREATERULE.ts b/packages/time-series/lib/commands/CREATERULE.ts index bd074d7107..99a8a4c9d5 100644 --- a/packages/time-series/lib/commands/CREATERULE.ts +++ b/packages/time-series/lib/commands/CREATERULE.ts @@ -1,4 +1,5 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export const TIME_SERIES_AGGREGATION_TYPE = { AVG: 'AVG', @@ -19,29 +20,22 @@ export const TIME_SERIES_AGGREGATION_TYPE = { export type TimeSeriesAggregationType = typeof TIME_SERIES_AGGREGATION_TYPE[keyof typeof TIME_SERIES_AGGREGATION_TYPE]; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments( + parseCommand( + parser: CommandParser, sourceKey: RedisArgument, destinationKey: RedisArgument, aggregationType: TimeSeriesAggregationType, bucketDuration: number, alignTimestamp?: number ) { - const args = [ - 'TS.CREATERULE', - sourceKey, - destinationKey, - 'AGGREGATION', - aggregationType, - bucketDuration.toString() - ]; + parser.push('TS.CREATERULE'); + parser.pushKeys([sourceKey, destinationKey]); + parser.push('AGGREGATION', aggregationType, bucketDuration.toString()); if (alignTimestamp !== undefined) { - args.push(alignTimestamp.toString()); + parser.push(alignTimestamp.toString()); } - - return args; }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/time-series/lib/commands/DECRBY.spec.ts b/packages/time-series/lib/commands/DECRBY.spec.ts index dbce98b2ac..b272ed1614 100644 --- a/packages/time-series/lib/commands/DECRBY.spec.ts +++ b/packages/time-series/lib/commands/DECRBY.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DECRBY from './DECRBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.DECRBY', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1), + parseArgs(DECRBY, 'key', 1), ['TS.DECRBY', 'key', '1'] ); }); it('with TIMESTAMP', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { TIMESTAMP: '*' }), ['TS.DECRBY', 'key', '1', 'TIMESTAMP', '*'] @@ -22,7 +23,7 @@ describe('TS.DECRBY', () => { it('with RETENTION', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { RETENTION: 1 }), ['TS.DECRBY', 'key', '1', 'RETENTION', '1'] @@ -31,7 +32,7 @@ describe('TS.DECRBY', () => { it('with UNCOMPRESSED', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { UNCOMPRESSED: true }), ['TS.DECRBY', 'key', '1', 'UNCOMPRESSED'] @@ -40,7 +41,7 @@ describe('TS.DECRBY', () => { it('with CHUNK_SIZE', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { CHUNK_SIZE: 100 }), ['TS.DECRBY', 'key', '1', 'CHUNK_SIZE', '100'] @@ -49,7 +50,7 @@ describe('TS.DECRBY', () => { it('with LABELS', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { LABELS: { label: 'value' } }), ['TS.DECRBY', 'key', '1', 'LABELS', 'label', 'value'] @@ -58,7 +59,7 @@ describe('TS.DECRBY', () => { it ('with IGNORE', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { IGNORE: { maxTimeDiff: 1, maxValDiff: 1 @@ -70,7 +71,7 @@ describe('TS.DECRBY', () => { it('with TIMESTAMP, RETENTION, UNCOMPRESSED, CHUNK_SIZE and LABELS', () => { assert.deepEqual( - DECRBY.transformArguments('key', 1, { + parseArgs(DECRBY, 'key', 1, { TIMESTAMP: '*', RETENTION: 1, UNCOMPRESSED: true, diff --git a/packages/time-series/lib/commands/DECRBY.ts b/packages/time-series/lib/commands/DECRBY.ts index a5ee01efb0..c2a7e6abd9 100644 --- a/packages/time-series/lib/commands/DECRBY.ts +++ b/packages/time-series/lib/commands/DECRBY.ts @@ -1,9 +1,13 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; -import INCRBY, { transformIncrByArguments } from './INCRBY'; +import { Command } from '@redis/client/lib/RESP/types'; +import INCRBY, { parseIncrByArguments } from './INCRBY'; export default { - FIRST_KEY_INDEX: INCRBY.FIRST_KEY_INDEX, IS_READ_ONLY: INCRBY.IS_READ_ONLY, - transformArguments: transformIncrByArguments.bind(undefined, 'TS.DECRBY'), + parseCommand(...args: Parameters) { + const parser = args[0]; + + parser.push('TS.DECRBY'); + parseIncrByArguments(...args); + }, transformReply: INCRBY.transformReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/DEL.spec.ts b/packages/time-series/lib/commands/DEL.spec.ts index afe6be77c4..07d29ca095 100644 --- a/packages/time-series/lib/commands/DEL.spec.ts +++ b/packages/time-series/lib/commands/DEL.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DEL from './DEL'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.DEL', () => { it('transformArguments', () => { assert.deepEqual( - DEL.transformArguments('key', '-', '+'), + parseArgs(DEL, 'key', '-', '+'), ['TS.DEL', 'key', '-', '+'] ); }); diff --git a/packages/time-series/lib/commands/DEL.ts b/packages/time-series/lib/commands/DEL.ts index 26c3e610f1..ad957e6c40 100644 --- a/packages/time-series/lib/commands/DEL.ts +++ b/packages/time-series/lib/commands/DEL.ts @@ -1,16 +1,13 @@ +import { CommandParser } from '@redis/client/lib/client/parser'; import { Timestamp, transformTimestampArgument } from '.'; -import { RedisArgument, NumberReply, Command, } from '@redis/client/dist/lib/RESP/types'; +import { RedisArgument, NumberReply, Command, } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(key: RedisArgument, fromTimestamp: Timestamp, toTimestamp: Timestamp) { - return [ - 'TS.DEL', - key, - transformTimestampArgument(fromTimestamp), - transformTimestampArgument(toTimestamp) - ]; + parseCommand(parser: CommandParser, key: RedisArgument, fromTimestamp: Timestamp, toTimestamp: Timestamp) { + parser.push('TS.DEL'); + parser.pushKey(key); + parser.push(transformTimestampArgument(fromTimestamp), transformTimestampArgument(toTimestamp)); }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/DELETERULE.spec.ts b/packages/time-series/lib/commands/DELETERULE.spec.ts index 8c8568c856..d7a19a8eaa 100644 --- a/packages/time-series/lib/commands/DELETERULE.spec.ts +++ b/packages/time-series/lib/commands/DELETERULE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import DELETERULE from './DELETERULE'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.DELETERULE', () => { it('transformArguments', () => { assert.deepEqual( - DELETERULE.transformArguments('source', 'destination'), + parseArgs(DELETERULE, 'source', 'destination'), ['TS.DELETERULE', 'source', 'destination'] ); }); diff --git a/packages/time-series/lib/commands/DELETERULE.ts b/packages/time-series/lib/commands/DELETERULE.ts index 5cf88897f7..8a1aa41385 100644 --- a/packages/time-series/lib/commands/DELETERULE.ts +++ b/packages/time-series/lib/commands/DELETERULE.ts @@ -1,14 +1,11 @@ -import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, SimpleStringReply, Command } from '@redis/client/lib/RESP/types'; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(sourceKey: RedisArgument, destinationKey: RedisArgument) { - return [ - 'TS.DELETERULE', - sourceKey, - destinationKey - ]; + parseCommand(parser: CommandParser, sourceKey: RedisArgument, destinationKey: RedisArgument) { + parser.push('TS.DELETERULE'); + parser.pushKeys([sourceKey, destinationKey]); }, transformReply: undefined as unknown as () => SimpleStringReply<'OK'> } as const satisfies Command; diff --git a/packages/time-series/lib/commands/GET.spec.ts b/packages/time-series/lib/commands/GET.spec.ts index a1f47346bc..836a1b638a 100644 --- a/packages/time-series/lib/commands/GET.spec.ts +++ b/packages/time-series/lib/commands/GET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import GET from './GET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.GET', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - GET.transformArguments('key'), + parseArgs(GET, 'key'), ['TS.GET', 'key'] ); }); it('with LATEST', () => { assert.deepEqual( - GET.transformArguments('key', { + parseArgs(GET, 'key', { LATEST: true }), ['TS.GET', 'key', 'LATEST'] diff --git a/packages/time-series/lib/commands/GET.ts b/packages/time-series/lib/commands/GET.ts index 78e5e3bced..9f165bed6e 100644 --- a/packages/time-series/lib/commands/GET.ts +++ b/packages/time-series/lib/commands/GET.ts @@ -1,4 +1,5 @@ -import { RedisArgument, TuplesReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, TuplesReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command } from '@redis/client/lib/RESP/types'; export interface TsGetOptions { LATEST?: boolean; @@ -7,16 +8,14 @@ export interface TsGetOptions { export type TsGetReply = TuplesReply<[]> | TuplesReply<[NumberReply, DoubleReply]>; export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: RedisArgument, options?: TsGetOptions) { - const args = ['TS.GET', key]; + parseCommand(parser: CommandParser, key: RedisArgument, options?: TsGetOptions) { + parser.push('TS.GET'); + parser.pushKey(key); if (options?.LATEST) { - args.push('LATEST'); + parser.push('LATEST'); } - - return args; }, transformReply: { 2(reply: UnwrapReply>) { diff --git a/packages/time-series/lib/commands/INCRBY.spec.ts b/packages/time-series/lib/commands/INCRBY.spec.ts index 33163a72c8..5d005952b3 100644 --- a/packages/time-series/lib/commands/INCRBY.spec.ts +++ b/packages/time-series/lib/commands/INCRBY.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import INCRBY from './INCRBY'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.INCRBY', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1), + parseArgs(INCRBY, 'key', 1), ['TS.INCRBY', 'key', '1'] ); }); it('with TIMESTAMP', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { TIMESTAMP: '*' }), ['TS.INCRBY', 'key', '1', 'TIMESTAMP', '*'] @@ -22,7 +23,7 @@ describe('TS.INCRBY', () => { it('with RETENTION', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { RETENTION: 1 }), ['TS.INCRBY', 'key', '1', 'RETENTION', '1'] @@ -31,7 +32,7 @@ describe('TS.INCRBY', () => { it('with UNCOMPRESSED', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { UNCOMPRESSED: true }), ['TS.INCRBY', 'key', '1', 'UNCOMPRESSED'] @@ -40,7 +41,7 @@ describe('TS.INCRBY', () => { it('without UNCOMPRESSED', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { UNCOMPRESSED: false }), ['TS.INCRBY', 'key', '1'] @@ -49,7 +50,7 @@ describe('TS.INCRBY', () => { it('with CHUNK_SIZE', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { CHUNK_SIZE: 1 }), ['TS.INCRBY', 'key', '1', 'CHUNK_SIZE', '1'] @@ -58,7 +59,7 @@ describe('TS.INCRBY', () => { it('with LABELS', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { LABELS: { label: 'value' } }), ['TS.INCRBY', 'key', '1', 'LABELS', 'label', 'value'] @@ -67,7 +68,7 @@ describe('TS.INCRBY', () => { it ('with IGNORE', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { IGNORE: { maxTimeDiff: 1, maxValDiff: 1 @@ -79,7 +80,7 @@ describe('TS.INCRBY', () => { it('with TIMESTAMP, RETENTION, UNCOMPRESSED, CHUNK_SIZE and LABELS', () => { assert.deepEqual( - INCRBY.transformArguments('key', 1, { + parseArgs(INCRBY, 'key', 1, { TIMESTAMP: '*', RETENTION: 1, UNCOMPRESSED: true, diff --git a/packages/time-series/lib/commands/INCRBY.ts b/packages/time-series/lib/commands/INCRBY.ts index 3160d3906d..7dbdb6b9ea 100644 --- a/packages/time-series/lib/commands/INCRBY.ts +++ b/packages/time-series/lib/commands/INCRBY.ts @@ -1,5 +1,6 @@ -import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { Timestamp, transformTimestampArgument, pushRetentionArgument, pushChunkSizeArgument, Labels, pushLabelsArgument, pushIgnoreArgument } from '.'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, NumberReply, Command } from '@redis/client/lib/RESP/types'; +import { Timestamp, transformTimestampArgument, parseRetentionArgument, parseChunkSizeArgument, Labels, parseLabelsArgument, parseIgnoreArgument } from '.'; import { TsIgnoreOptions } from './ADD'; export interface TsIncrByOptions { @@ -11,40 +12,39 @@ export interface TsIncrByOptions { IGNORE?: TsIgnoreOptions; } -export function transformIncrByArguments( - command: RedisArgument, +export function parseIncrByArguments( + parser: CommandParser, key: RedisArgument, value: number, options?: TsIncrByOptions ) { - const args = [ - command, - key, - value.toString() - ]; + parser.pushKey(key); + parser.push(value.toString()); if (options?.TIMESTAMP !== undefined && options?.TIMESTAMP !== null) { - args.push('TIMESTAMP', transformTimestampArgument(options.TIMESTAMP)); + parser.push('TIMESTAMP', transformTimestampArgument(options.TIMESTAMP)); } - pushRetentionArgument(args, options?.RETENTION); + parseRetentionArgument(parser, options?.RETENTION); if (options?.UNCOMPRESSED) { - args.push('UNCOMPRESSED'); + parser.push('UNCOMPRESSED'); } - pushChunkSizeArgument(args, options?.CHUNK_SIZE); + parseChunkSizeArgument(parser, options?.CHUNK_SIZE); - pushLabelsArgument(args, options?.LABELS); + parseLabelsArgument(parser, options?.LABELS); - pushIgnoreArgument(args, options?.IGNORE); - - return args; + parseIgnoreArgument(parser, options?.IGNORE); } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments: transformIncrByArguments.bind(undefined, 'TS.INCRBY'), + parseCommand(...args: Parameters) { + const parser = args[0]; + + parser.push('TS.INCRBY'); + parseIncrByArguments(...args); + }, transformReply: undefined as unknown as () => NumberReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/INFO.spec.ts b/packages/time-series/lib/commands/INFO.spec.ts index e4295b80fa..73b9d8dc93 100644 --- a/packages/time-series/lib/commands/INFO.spec.ts +++ b/packages/time-series/lib/commands/INFO.spec.ts @@ -3,11 +3,12 @@ import { TIME_SERIES_DUPLICATE_POLICIES } from '.'; import testUtils, { GLOBAL } from '../test-utils'; import INFO, { InfoReply } from './INFO'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.INFO', () => { it('transformArguments', () => { assert.deepEqual( - INFO.transformArguments('key'), + parseArgs(INFO, 'key'), ['TS.INFO', 'key'] ); }); diff --git a/packages/time-series/lib/commands/INFO.ts b/packages/time-series/lib/commands/INFO.ts index 91d4e4bbad..fbd66875b1 100644 --- a/packages/time-series/lib/commands/INFO.ts +++ b/packages/time-series/lib/commands/INFO.ts @@ -1,3 +1,4 @@ +import { CommandParser } from '@redis/client/lib/client/parser'; import { ArrayReply, BlobStringReply, Command, DoubleReply, NumberReply, ReplyUnion, SimpleStringReply, TypeMapping } from "@redis/client/lib/RESP/types"; import { TimeSeriesDuplicatePolicies } from "."; import { TimeSeriesAggregationType } from "./CREATERULE"; @@ -71,10 +72,10 @@ export interface InfoReply { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments(key: string) { - return ['TS.INFO', key]; + parseCommand(parser: CommandParser, key: string) { + parser.push('TS.INFO'); + parser.pushKey(key); }, transformReply: { 2: (reply: InfoRawReply, _, typeMapping?: TypeMapping): InfoReply => { @@ -125,4 +126,4 @@ export default { 3: undefined as unknown as () => ReplyUnion }, unstableResp3: true - } as const satisfies Command; \ No newline at end of file + } as const satisfies Command; diff --git a/packages/time-series/lib/commands/INFO_DEBUG.spec.ts b/packages/time-series/lib/commands/INFO_DEBUG.spec.ts index 674f91c60a..063b912655 100644 --- a/packages/time-series/lib/commands/INFO_DEBUG.spec.ts +++ b/packages/time-series/lib/commands/INFO_DEBUG.spec.ts @@ -4,11 +4,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import { assertInfo } from './INFO.spec'; import INFO_DEBUG from './INFO_DEBUG'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.INFO_DEBUG', () => { it('transformArguments', () => { assert.deepEqual( - INFO_DEBUG.transformArguments('key'), + parseArgs(INFO_DEBUG, 'key'), ['TS.INFO', 'key', 'DEBUG'] ); }); diff --git a/packages/time-series/lib/commands/INFO_DEBUG.ts b/packages/time-series/lib/commands/INFO_DEBUG.ts index fb2b28b807..bee1147f2b 100644 --- a/packages/time-series/lib/commands/INFO_DEBUG.ts +++ b/packages/time-series/lib/commands/INFO_DEBUG.ts @@ -1,6 +1,6 @@ -import { BlobStringReply, Command, NumberReply, SimpleStringReply, TypeMapping } from "@redis/client/lib/RESP/types"; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { BlobStringReply, Command, NumberReply, SimpleStringReply, TypeMapping, ReplyUnion } from "@redis/client/lib/RESP/types"; import INFO, { InfoRawReply, InfoRawReplyTypes, InfoReply } from "./INFO"; -import { ReplyUnion } from '@redis/client/lib/RESP/types'; type chunkType = Array<[ 'startTimestamp', @@ -37,12 +37,10 @@ export interface InfoDebugReply extends InfoReply { } export default { - FIRST_KEY_INDEX: INFO.FIRST_KEY_INDEX, IS_READ_ONLY: INFO.IS_READ_ONLY, - transformArguments(key: string) { - const args = INFO.transformArguments(key); - args.push('DEBUG'); - return args; + parseCommand(parser: CommandParser, key: string) { + INFO.parseCommand(parser, key); + parser.push('DEBUG'); }, transformReply: { 2: (reply: InfoDebugRawReply, _, typeMapping?: TypeMapping): InfoDebugReply => { @@ -76,4 +74,4 @@ export default { 3: undefined as unknown as () => ReplyUnion }, unstableResp3: true -} as const satisfies Command; \ No newline at end of file +} as const satisfies Command; diff --git a/packages/time-series/lib/commands/MADD.spec.ts b/packages/time-series/lib/commands/MADD.spec.ts index bbe358e543..8bf8e27fdb 100644 --- a/packages/time-series/lib/commands/MADD.spec.ts +++ b/packages/time-series/lib/commands/MADD.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MADD from './MADD'; import { SimpleError } from '@redis/client/lib/errors'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MADD', () => { it('transformArguments', () => { assert.deepEqual( - MADD.transformArguments([{ + parseArgs(MADD, [{ key: '1', timestamp: 0, value: 0 diff --git a/packages/time-series/lib/commands/MADD.ts b/packages/time-series/lib/commands/MADD.ts index 59c1ed59bd..cb1f077055 100644 --- a/packages/time-series/lib/commands/MADD.ts +++ b/packages/time-series/lib/commands/MADD.ts @@ -1,5 +1,6 @@ +import { CommandParser } from '@redis/client/lib/client/parser'; import { Timestamp, transformTimestampArgument } from '.'; -import { ArrayReply, NumberReply, SimpleErrorReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { ArrayReply, NumberReply, SimpleErrorReply, Command } from '@redis/client/lib/RESP/types'; export interface TsMAddSample { key: string; @@ -8,20 +9,14 @@ export interface TsMAddSample { } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: false, - transformArguments(toAdd: Array) { - const args = ['TS.MADD']; + parseCommand(parser: CommandParser, toAdd: Array) { + parser.push('TS.MADD'); for (const { key, timestamp, value } of toAdd) { - args.push( - key, - transformTimestampArgument(timestamp), - value.toString() - ); + parser.pushKey(key); + parser.push(transformTimestampArgument(timestamp), value.toString()); } - - return args; }, transformReply: undefined as unknown as () => ArrayReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MGET.spec.ts b/packages/time-series/lib/commands/MGET.spec.ts index b2de0486cf..ba2e571be4 100644 --- a/packages/time-series/lib/commands/MGET.spec.ts +++ b/packages/time-series/lib/commands/MGET.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MGET from './MGET'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MGET', () => { describe('transformArguments', () => { it('without options', () => { assert.deepEqual( - MGET.transformArguments('label=value'), + parseArgs(MGET, 'label=value'), ['TS.MGET', 'FILTER', 'label=value'] ); }); it('with LATEST', () => { assert.deepEqual( - MGET.transformArguments('label=value', { + parseArgs(MGET, 'label=value', { LATEST: true }), ['TS.MGET', 'LATEST', 'FILTER', 'label=value'] diff --git a/packages/time-series/lib/commands/MGET.ts b/packages/time-series/lib/commands/MGET.ts index 2b04b29589..add742a70d 100644 --- a/packages/time-series/lib/commands/MGET.ts +++ b/packages/time-series/lib/commands/MGET.ts @@ -1,22 +1,21 @@ -import { CommandArguments, Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/lib/RESP/types'; import { resp2MapToValue, resp3MapToValue, SampleRawReply, transformSampleReply } from '.'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export interface TsMGetOptions { LATEST?: boolean; } -export function pushLatestArgument(args: CommandArguments, latest?: boolean) { +export function parseLatestArgument(parser: CommandParser, latest?: boolean) { if (latest) { - args.push('LATEST'); + parser.push('LATEST'); } - - return args; } -export function pushFilterArgument(args: CommandArguments, filter: RedisVariadicArgument) { - args.push('FILTER'); - return pushVariadicArguments(args, filter); +export function parseFilterArgument(parser: CommandParser, filter: RedisVariadicArgument) { + parser.push('FILTER'); + parser.pushVariadic(filter); } export type MGetRawReply2 = ArrayReply< @@ -36,11 +35,12 @@ export type MGetRawReply3 = MapReply< >; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(filter: RedisVariadicArgument, options?: TsMGetOptions) { - const args = pushLatestArgument(['TS.MGET'], options?.LATEST); - return pushFilterArgument(args, filter); + parseCommand(parser: CommandParser, filter: RedisVariadicArgument, options?: TsMGetOptions) { + parser.push('TS.MGET'); + parseLatestArgument(parser, options?.LATEST); + parseFilterArgument(parser, filter); }, transformReply: { 2(reply: MGetRawReply2, _, typeMapping?: TypeMapping) { diff --git a/packages/time-series/lib/commands/MGET_SELECTED_LABELS.spec.ts b/packages/time-series/lib/commands/MGET_SELECTED_LABELS.spec.ts index d9820027bb..d79c463fc7 100644 --- a/packages/time-series/lib/commands/MGET_SELECTED_LABELS.spec.ts +++ b/packages/time-series/lib/commands/MGET_SELECTED_LABELS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MGET_SELECTED_LABELS from './MGET_SELECTED_LABELS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MGET_SELECTED_LABELS', () => { it('transformArguments', () => { assert.deepEqual( - MGET_SELECTED_LABELS.transformArguments('label=value', 'label'), + parseArgs(MGET_SELECTED_LABELS, 'label=value', 'label'), ['TS.MGET', 'SELECTED_LABELS', 'label', 'FILTER', 'label=value'] ); }); diff --git a/packages/time-series/lib/commands/MGET_SELECTED_LABELS.ts b/packages/time-series/lib/commands/MGET_SELECTED_LABELS.ts index d132972d87..67c7dc7960 100644 --- a/packages/time-series/lib/commands/MGET_SELECTED_LABELS.ts +++ b/packages/time-series/lib/commands/MGET_SELECTED_LABELS.ts @@ -1,16 +1,17 @@ -import { Command, BlobStringReply, NullReply } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; -import { TsMGetOptions, pushLatestArgument, pushFilterArgument } from './MGET'; -import { pushSelectedLabelsArguments } from '.'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, BlobStringReply, NullReply } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { TsMGetOptions, parseLatestArgument, parseFilterArgument } from './MGET'; +import { parseSelectedLabelsArguments } from '.'; import { createTransformMGetLabelsReply } from './MGET_WITHLABELS'; export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments(filter: RedisVariadicArgument, selectedLabels: RedisVariadicArgument, options?: TsMGetOptions) { - let args = pushLatestArgument(['TS.MGET'], options?.LATEST); - args = pushSelectedLabelsArguments(args, selectedLabels); - return pushFilterArgument(args, filter); + parseCommand(parser: CommandParser, filter: RedisVariadicArgument, selectedLabels: RedisVariadicArgument, options?: TsMGetOptions) { + parser.push('TS.MGET'); + parseLatestArgument(parser, options?.LATEST); + parseSelectedLabelsArguments(parser, selectedLabels); + parseFilterArgument(parser, filter); }, transformReply: createTransformMGetLabelsReply(), } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MGET_WITHLABELS.spec.ts b/packages/time-series/lib/commands/MGET_WITHLABELS.spec.ts index d3e51d2cab..33fc530844 100644 --- a/packages/time-series/lib/commands/MGET_WITHLABELS.spec.ts +++ b/packages/time-series/lib/commands/MGET_WITHLABELS.spec.ts @@ -1,11 +1,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MGET_WITHLABELS from './MGET_WITHLABELS'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MGET_WITHLABELS', () => { it('transformArguments', () => { assert.deepEqual( - MGET_WITHLABELS.transformArguments('label=value'), + parseArgs(MGET_WITHLABELS, 'label=value'), ['TS.MGET', 'WITHLABELS', 'FILTER', 'label=value'] ); }); diff --git a/packages/time-series/lib/commands/MGET_WITHLABELS.ts b/packages/time-series/lib/commands/MGET_WITHLABELS.ts index 679a536f2a..f6d50c91b1 100644 --- a/packages/time-series/lib/commands/MGET_WITHLABELS.ts +++ b/packages/time-series/lib/commands/MGET_WITHLABELS.ts @@ -1,6 +1,7 @@ -import { Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; -import { TsMGetOptions, pushLatestArgument, pushFilterArgument } from './MGET'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { TsMGetOptions, parseLatestArgument, parseFilterArgument } from './MGET'; import { RawLabelValue, resp2MapToValue, resp3MapToValue, SampleRawReply, transformRESP2Labels, transformSampleReply } from '.'; export interface TsMGetWithLabelsOptions extends TsMGetOptions { @@ -50,12 +51,12 @@ export function createTransformMGetLabelsReply() { } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments(filter: RedisVariadicArgument, options?: TsMGetOptions) { - const args = pushLatestArgument(['TS.MGET'], options?.LATEST); - args.push('WITHLABELS'); - return pushFilterArgument(args, filter); + parseCommand(parser: CommandParser, filter: RedisVariadicArgument, options?: TsMGetWithLabelsOptions) { + parser.push('TS.MGET'); + parseLatestArgument(parser, options?.LATEST); + parser.push('WITHLABELS'); + parseFilterArgument(parser, filter); }, transformReply: createTransformMGetLabelsReply(), } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MRANGE.spec.ts b/packages/time-series/lib/commands/MRANGE.spec.ts index 9d41763eb0..94c8e72983 100644 --- a/packages/time-series/lib/commands/MRANGE.spec.ts +++ b/packages/time-series/lib/commands/MRANGE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MRANGE from './MRANGE'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE.transformArguments('-', '+', 'label=value', { + parseArgs(MRANGE, '-', '+', 'label=value', { LATEST: true, FILTER_BY_TS: [0], FILTER_BY_VALUE: { diff --git a/packages/time-series/lib/commands/MRANGE.ts b/packages/time-series/lib/commands/MRANGE.ts index bbc93a70da..dbe48d6f54 100644 --- a/packages/time-series/lib/commands/MRANGE.ts +++ b/packages/time-series/lib/commands/MRANGE.ts @@ -1,8 +1,9 @@ -import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { pushFilterArgument } from './MGET'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { parseFilterArgument } from './MGET'; export type TsMRangeRawReply2 = ArrayReply< TuplesReply<[ @@ -23,26 +24,28 @@ export type TsMRangeRawReply3 = MapReply< export function createTransformMRangeArguments(command: RedisArgument) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, filter: RedisVariadicArgument, options?: TsRangeOptions ) => { - const args = pushRangeArguments( - [command], + parser.push(command); + parseRangeArguments( + parser, fromTimestamp, toTimestamp, options ); - return pushFilterArgument(args, filter); + parseFilterArgument(parser, filter); }; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments: createTransformMRangeArguments('TS.MRANGE'), + parseCommand: createTransformMRangeArguments('TS.MRANGE'), transformReply: { 2(reply: TsMRangeRawReply2, _?: any, typeMapping?: TypeMapping) { return resp2MapToValue(reply, ([_key, _labels, samples]) => { diff --git a/packages/time-series/lib/commands/MRANGE_GROUPBY.spec.ts b/packages/time-series/lib/commands/MRANGE_GROUPBY.spec.ts index c0d05425ff..bcdde20fe9 100644 --- a/packages/time-series/lib/commands/MRANGE_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MRANGE_GROUPBY.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MRANGE_GROUPBY, { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE_GROUPBY.transformArguments('-', '+', 'label=value', { + parseArgs(MRANGE_GROUPBY, '-', '+', 'label=value', { REDUCE: TIME_SERIES_REDUCERS.AVG, label: 'label' }, { diff --git a/packages/time-series/lib/commands/MRANGE_GROUPBY.ts b/packages/time-series/lib/commands/MRANGE_GROUPBY.ts index 3b4e94eac2..0d996521d1 100644 --- a/packages/time-series/lib/commands/MRANGE_GROUPBY.ts +++ b/packages/time-series/lib/commands/MRANGE_GROUPBY.ts @@ -1,8 +1,9 @@ -import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument, TuplesToMapReply, UnwrapReply } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument, TuplesToMapReply, UnwrapReply } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { pushFilterArgument } from './MGET'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { parseFilterArgument } from './MGET'; export const TIME_SERIES_REDUCERS = { AVG: 'AVG', @@ -24,8 +25,8 @@ export interface TsMRangeGroupBy { REDUCE: TimeSeriesReducer; } -export function pushGroupByArguments(args: Array, groupBy: TsMRangeGroupBy) { - args.push('GROUPBY', groupBy.label, 'REDUCE', groupBy.REDUCE); +export function parseGroupByArguments(parser: CommandParser, groupBy: TsMRangeGroupBy) { + parser.push('GROUPBY', groupBy.label, 'REDUCE', groupBy.REDUCE); } export type TsMRangeGroupByRawReply2 = ArrayReply< @@ -52,24 +53,19 @@ export type TsMRangeGroupByRawReply3 = MapReply< export function createTransformMRangeGroupByArguments(command: RedisArgument) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, filter: RedisVariadicArgument, groupBy: TsMRangeGroupBy, options?: TsRangeOptions ) => { - let args = pushRangeArguments( - [command], - fromTimestamp, - toTimestamp, - options - ); - - args = pushFilterArgument(args, filter); - - pushGroupByArguments(args, groupBy); + parser.push(command); + parseRangeArguments(parser, fromTimestamp, toTimestamp, options) - return args; + parseFilterArgument(parser, filter); + + parseGroupByArguments(parser, groupBy); }; } @@ -85,9 +81,8 @@ export function extractResp3MRangeSources(raw: TsMRangeGroupByRawMetadataReply3) } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments: createTransformMRangeGroupByArguments('TS.MRANGE'), + parseCommand: createTransformMRangeGroupByArguments('TS.MRANGE'), transformReply: { 2(reply: TsMRangeGroupByRawReply2, _?: any, typeMapping?: TypeMapping) { return resp2MapToValue(reply, ([_key, _labels, samples]) => { diff --git a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.spec.ts b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.spec.ts index 5c15bad89e..92680dea37 100644 --- a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.spec.ts +++ b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MRANGE_SELECTED_LABELS from './MRANGE_SELECTED_LABELS'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE_SELECTED_LABELS', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE_SELECTED_LABELS.transformArguments('-', '+', 'label', 'label=value', { + parseArgs(MRANGE_SELECTED_LABELS, '-', '+', 'label', 'label=value', { FILTER_BY_TS: [0], FILTER_BY_VALUE: { min: 0, diff --git a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.ts b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.ts index f91f958333..115944a2f4 100644 --- a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.ts +++ b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS.ts @@ -1,8 +1,9 @@ -import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, NullReply, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; -import { pushSelectedLabelsArguments, resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformRESP2Labels, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { pushFilterArgument } from './MGET'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, NullReply, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { parseSelectedLabelsArguments, resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformRESP2Labels, transformSamplesReply } from '.'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { parseFilterArgument } from './MGET'; export type TsMRangeSelectedLabelsRawReply2 = ArrayReply< TuplesReply<[ @@ -26,29 +27,30 @@ export type TsMRangeSelectedLabelsRawReply3 = MapReply< export function createTransformMRangeSelectedLabelsArguments(command: RedisArgument) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, selectedLabels: RedisVariadicArgument, filter: RedisVariadicArgument, options?: TsRangeOptions ) => { - let args = pushRangeArguments( - [command], + parser.push(command); + parseRangeArguments( + parser, fromTimestamp, toTimestamp, options ); - args = pushSelectedLabelsArguments(args, selectedLabels); + parseSelectedLabelsArguments(parser, selectedLabels); - return pushFilterArgument(args, filter); + parseFilterArgument(parser, filter); }; } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments: createTransformMRangeSelectedLabelsArguments('TS.MRANGE'), + parseCommand: createTransformMRangeSelectedLabelsArguments('TS.MRANGE'), transformReply: { 2(reply: TsMRangeSelectedLabelsRawReply2, _?: any, typeMapping?: TypeMapping) { return resp2MapToValue(reply, ([_key, labels, samples]) => { diff --git a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.spec.ts b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.spec.ts index 90090a851a..4e5b2b4709 100644 --- a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.spec.ts @@ -3,11 +3,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import MRANGE_SELECTED_LABELS_GROUPBY from './MRANGE_SELECTED_LABELS_GROUPBY'; import { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE_SELECTED_LABELS_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE_SELECTED_LABELS_GROUPBY.transformArguments('-', '+', 'label', 'label=value', { + parseArgs(MRANGE_SELECTED_LABELS_GROUPBY, '-', '+', 'label', 'label=value', { REDUCE: TIME_SERIES_REDUCERS.AVG, label: 'label' }, { diff --git a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.ts b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.ts index 7a798c4113..b4e8006a84 100644 --- a/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.ts +++ b/packages/time-series/lib/commands/MRANGE_SELECTED_LABELS_GROUPBY.ts @@ -1,9 +1,10 @@ -import { Command, ArrayReply, BlobStringReply, MapReply, TuplesReply, RedisArgument, NullReply } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; -import { pushSelectedLabelsArguments, resp3MapToValue, SampleRawReply, Timestamp, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { extractResp3MRangeSources, pushGroupByArguments, TsMRangeGroupBy, TsMRangeGroupByRawMetadataReply3 } from './MRANGE_GROUPBY'; -import { pushFilterArgument } from './MGET'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ArrayReply, BlobStringReply, MapReply, TuplesReply, RedisArgument, NullReply } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { parseSelectedLabelsArguments, resp3MapToValue, SampleRawReply, Timestamp, transformSamplesReply } from '.'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { extractResp3MRangeSources, parseGroupByArguments, TsMRangeGroupBy, TsMRangeGroupByRawMetadataReply3 } from './MRANGE_GROUPBY'; +import { parseFilterArgument } from './MGET'; import MRANGE_SELECTED_LABELS from './MRANGE_SELECTED_LABELS'; export type TsMRangeWithLabelsGroupByRawReply3 = MapReply< @@ -20,6 +21,7 @@ export function createMRangeSelectedLabelsGroupByTransformArguments( command: RedisArgument ) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, selectedLabels: RedisVariadicArgument, @@ -27,27 +29,25 @@ export function createMRangeSelectedLabelsGroupByTransformArguments( groupBy: TsMRangeGroupBy, options?: TsRangeOptions ) => { - let args = pushRangeArguments( - [command], + parser.push(command); + parseRangeArguments( + parser, fromTimestamp, toTimestamp, options ); - args = pushSelectedLabelsArguments(args, selectedLabels); + parseSelectedLabelsArguments(parser, selectedLabels); - args = pushFilterArgument(args, filter); + parseFilterArgument(parser, filter); - pushGroupByArguments(args, groupBy); - - return args; + parseGroupByArguments(parser, groupBy); }; } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments: createMRangeSelectedLabelsGroupByTransformArguments('TS.MRANGE'), + parseCommand: createMRangeSelectedLabelsGroupByTransformArguments('TS.MRANGE'), transformReply: { 2: MRANGE_SELECTED_LABELS.transformReply[2], 3(reply: TsMRangeWithLabelsGroupByRawReply3) { diff --git a/packages/time-series/lib/commands/MRANGE_WITHLABELS.spec.ts b/packages/time-series/lib/commands/MRANGE_WITHLABELS.spec.ts index fabf04b60d..eab2e1fadb 100644 --- a/packages/time-series/lib/commands/MRANGE_WITHLABELS.spec.ts +++ b/packages/time-series/lib/commands/MRANGE_WITHLABELS.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MRANGE_WITHLABELS from './MRANGE_WITHLABELS'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE_WITHLABELS', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE_WITHLABELS.transformArguments('-', '+', 'label=value', { + parseArgs(MRANGE_WITHLABELS, '-', '+', 'label=value', { LATEST: true, FILTER_BY_TS: [0], FILTER_BY_VALUE: { diff --git a/packages/time-series/lib/commands/MRANGE_WITHLABELS.ts b/packages/time-series/lib/commands/MRANGE_WITHLABELS.ts index ab7a4ec8f6..04d72411b7 100644 --- a/packages/time-series/lib/commands/MRANGE_WITHLABELS.ts +++ b/packages/time-series/lib/commands/MRANGE_WITHLABELS.ts @@ -1,8 +1,9 @@ -import { Command, UnwrapReply, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, UnwrapReply, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { pushFilterArgument } from './MGET'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { parseFilterArgument } from './MGET'; export type TsMRangeWithLabelsRawReply2 = ArrayReply< TuplesReply<[ @@ -26,28 +27,30 @@ export type TsMRangeWithLabelsRawReply3 = MapReply< export function createTransformMRangeWithLabelsArguments(command: RedisArgument) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, filter: RedisVariadicArgument, options?: TsRangeOptions ) => { - const args = pushRangeArguments( - [command], + parser.push(command); + parseRangeArguments( + parser, fromTimestamp, toTimestamp, options ); - args.push('WITHLABELS'); + parser.push('WITHLABELS'); - return pushFilterArgument(args, filter); + parseFilterArgument(parser, filter); }; } export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments: createTransformMRangeWithLabelsArguments('TS.MRANGE'), + parseCommand: createTransformMRangeWithLabelsArguments('TS.MRANGE'), transformReply: { 2(reply: TsMRangeWithLabelsRawReply2, _?: any, typeMapping?: TypeMapping) { return resp2MapToValue(reply, ([_key, labels, samples]) => { diff --git a/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.spec.ts b/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.spec.ts index 755c3aca32..4a8b8fe707 100644 --- a/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.spec.ts @@ -3,11 +3,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import MRANGE_WITHLABELS_GROUPBY from './MRANGE_WITHLABELS_GROUPBY'; import { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MRANGE_WITHLABELS_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MRANGE_WITHLABELS_GROUPBY.transformArguments('-', '+', 'label=value', { + parseArgs(MRANGE_WITHLABELS_GROUPBY, '-', '+', 'label=value', { label: 'label', REDUCE: TIME_SERIES_REDUCERS.AVG }, { diff --git a/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.ts b/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.ts index 7c5e0af368..f09d630dcd 100644 --- a/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.ts +++ b/packages/time-series/lib/commands/MRANGE_WITHLABELS_GROUPBY.ts @@ -1,9 +1,10 @@ -import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { Command, ArrayReply, BlobStringReply, Resp2Reply, MapReply, TuplesReply, TypeMapping, RedisArgument } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; import { resp2MapToValue, resp3MapToValue, SampleRawReply, Timestamp, transformRESP2LabelsWithSources, transformSamplesReply } from '.'; -import { TsRangeOptions, pushRangeArguments } from './RANGE'; -import { extractResp3MRangeSources, pushGroupByArguments, TsMRangeGroupBy, TsMRangeGroupByRawMetadataReply3 } from './MRANGE_GROUPBY'; -import { pushFilterArgument } from './MGET'; +import { TsRangeOptions, parseRangeArguments } from './RANGE'; +import { extractResp3MRangeSources, parseGroupByArguments, TsMRangeGroupBy, TsMRangeGroupByRawMetadataReply3 } from './MRANGE_GROUPBY'; +import { parseFilterArgument } from './MGET'; export type TsMRangeWithLabelsGroupByRawReply2 = ArrayReply< TuplesReply<[ @@ -28,33 +29,32 @@ export type TsMRangeWithLabelsGroupByRawReply3 = MapReply< export function createMRangeWithLabelsGroupByTransformArguments(command: RedisArgument) { return ( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, filter: RedisVariadicArgument, groupBy: TsMRangeGroupBy, options?: TsRangeOptions ) => { - let args = pushRangeArguments( - [command], + parser.push(command); + parseRangeArguments( + parser, fromTimestamp, toTimestamp, options ); - args.push('WITHLABELS'); + parser.push('WITHLABELS'); - args = pushFilterArgument(args, filter); + parseFilterArgument(parser, filter); - pushGroupByArguments(args, groupBy); - - return args; - }; + parseGroupByArguments(parser, groupBy); + }; } export default { - FIRST_KEY_INDEX: undefined, IS_READ_ONLY: true, - transformArguments: createMRangeWithLabelsGroupByTransformArguments('TS.MRANGE'), + parseCommand: createMRangeWithLabelsGroupByTransformArguments('TS.MRANGE'), transformReply: { 2(reply: TsMRangeWithLabelsGroupByRawReply2, _?: any, typeMapping?: TypeMapping) { return resp2MapToValue(reply, ([_key, labels, samples]) => { diff --git a/packages/time-series/lib/commands/MREVRANGE.spec.ts b/packages/time-series/lib/commands/MREVRANGE.spec.ts index 8d6b8d3c14..09051103f8 100644 --- a/packages/time-series/lib/commands/MREVRANGE.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE from './MREVRANGE'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE.transformArguments('-', '+', 'label=value', { + parseArgs(MREVRANGE, '-', '+', 'label=value', { LATEST: true, FILTER_BY_TS: [0], FILTER_BY_VALUE: { diff --git a/packages/time-series/lib/commands/MREVRANGE.ts b/packages/time-series/lib/commands/MREVRANGE.ts index 097176e683..e2ed6d9cc9 100644 --- a/packages/time-series/lib/commands/MREVRANGE.ts +++ b/packages/time-series/lib/commands/MREVRANGE.ts @@ -1,9 +1,9 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE, { createTransformMRangeArguments } from './MRANGE'; export default { - FIRST_KEY_INDEX: MRANGE.FIRST_KEY_INDEX, + NOT_KEYED_COMMAND: MRANGE.NOT_KEYED_COMMAND, IS_READ_ONLY: MRANGE.IS_READ_ONLY, - transformArguments: createTransformMRangeArguments('TS.MREVRANGE'), + parseCommand: createTransformMRangeArguments('TS.MREVRANGE'), transformReply: MRANGE.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MREVRANGE_GROUPBY.spec.ts b/packages/time-series/lib/commands/MREVRANGE_GROUPBY.spec.ts index 9ccebc6c51..d32d675ad0 100644 --- a/packages/time-series/lib/commands/MREVRANGE_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE_GROUPBY.spec.ts @@ -3,11 +3,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE_GROUPBY from './MREVRANGE_GROUPBY'; import { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE_GROUPBY.transformArguments('-', '+', 'label=value', { + parseArgs(MREVRANGE_GROUPBY, '-', '+', 'label=value', { REDUCE: TIME_SERIES_REDUCERS.AVG, label: 'label' }, { diff --git a/packages/time-series/lib/commands/MREVRANGE_GROUPBY.ts b/packages/time-series/lib/commands/MREVRANGE_GROUPBY.ts index 24b2e6142f..efdd1acdcf 100644 --- a/packages/time-series/lib/commands/MREVRANGE_GROUPBY.ts +++ b/packages/time-series/lib/commands/MREVRANGE_GROUPBY.ts @@ -1,9 +1,8 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE_GROUPBY, { createTransformMRangeGroupByArguments } from './MRANGE_GROUPBY'; export default { - FIRST_KEY_INDEX: MRANGE_GROUPBY.FIRST_KEY_INDEX, IS_READ_ONLY: MRANGE_GROUPBY.IS_READ_ONLY, - transformArguments: createTransformMRangeGroupByArguments('TS.MREVRANGE'), + parseCommand: createTransformMRangeGroupByArguments('TS.MREVRANGE'), transformReply: MRANGE_GROUPBY.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.spec.ts b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.spec.ts index f0533010b8..f68e34727c 100644 --- a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE_SELECTED_LABELS from './MREVRANGE_SELECTED_LABELS'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE_SELECTED_LABELS', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE_SELECTED_LABELS.transformArguments('-', '+', 'label', 'label=value', { + parseArgs(MREVRANGE_SELECTED_LABELS, '-', '+', 'label', 'label=value', { FILTER_BY_TS: [0], FILTER_BY_VALUE: { min: 0, diff --git a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.ts b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.ts index 8656b768c2..8b679e65b6 100644 --- a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.ts +++ b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS.ts @@ -1,9 +1,8 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE_SELECTED_LABELS, { createTransformMRangeSelectedLabelsArguments } from './MRANGE_SELECTED_LABELS'; export default { - FIRST_KEY_INDEX: MRANGE_SELECTED_LABELS.FIRST_KEY_INDEX, IS_READ_ONLY: MRANGE_SELECTED_LABELS.IS_READ_ONLY, - transformArguments: createTransformMRangeSelectedLabelsArguments('TS.MREVRANGE'), + parseCommand: createTransformMRangeSelectedLabelsArguments('TS.MREVRANGE'), transformReply: MRANGE_SELECTED_LABELS.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.spec.ts b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.spec.ts index 34ef4ff79a..444bb2f3d2 100644 --- a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.spec.ts @@ -3,11 +3,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE_SELECTED_LABELS_GROUPBY from './MREVRANGE_SELECTED_LABELS_GROUPBY'; import { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE_SELECTED_LABELS_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE_SELECTED_LABELS_GROUPBY.transformArguments('-', '+', 'label', 'label=value', { + parseArgs(MREVRANGE_SELECTED_LABELS_GROUPBY, '-', '+', 'label', 'label=value', { REDUCE: TIME_SERIES_REDUCERS.AVG, label: 'label' }, { diff --git a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.ts b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.ts index f47330367b..d01ebe1033 100644 --- a/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.ts +++ b/packages/time-series/lib/commands/MREVRANGE_SELECTED_LABELS_GROUPBY.ts @@ -1,9 +1,8 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE_SELECTED_LABELS_GROUPBY, { createMRangeSelectedLabelsGroupByTransformArguments } from './MRANGE_SELECTED_LABELS_GROUPBY'; export default { - FIRST_KEY_INDEX: MRANGE_SELECTED_LABELS_GROUPBY.FIRST_KEY_INDEX, IS_READ_ONLY: MRANGE_SELECTED_LABELS_GROUPBY.IS_READ_ONLY, - transformArguments: createMRangeSelectedLabelsGroupByTransformArguments('TS.MREVRANGE'), + parseCommand: createMRangeSelectedLabelsGroupByTransformArguments('TS.MREVRANGE'), transformReply: MRANGE_SELECTED_LABELS_GROUPBY.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.spec.ts b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.spec.ts index eb88f233e4..da43a715f2 100644 --- a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE_WITHLABELS from './MREVRANGE_WITHLABELS'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE_WITHLABELS', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE_WITHLABELS.transformArguments('-', '+', 'label=value', { + parseArgs(MREVRANGE_WITHLABELS, '-', '+', 'label=value', { LATEST: true, FILTER_BY_TS: [0], FILTER_BY_VALUE: { diff --git a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.ts b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.ts index 81356d845f..d4f6255592 100644 --- a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.ts +++ b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS.ts @@ -1,9 +1,9 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE_WITHLABELS, { createTransformMRangeWithLabelsArguments } from './MRANGE_WITHLABELS'; export default { - FIRST_KEY_INDEX: MRANGE_WITHLABELS.FIRST_KEY_INDEX, + NOT_KEYED_COMMAND: MRANGE_WITHLABELS.NOT_KEYED_COMMAND, IS_READ_ONLY: MRANGE_WITHLABELS.IS_READ_ONLY, - transformArguments: createTransformMRangeWithLabelsArguments('TS.MREVRANGE'), + parseCommand: createTransformMRangeWithLabelsArguments('TS.MREVRANGE'), transformReply: MRANGE_WITHLABELS.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.spec.ts b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.spec.ts index da2c358b33..f4e6df9f0c 100644 --- a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.spec.ts +++ b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.spec.ts @@ -3,11 +3,12 @@ import testUtils, { GLOBAL } from '../test-utils'; import MREVRANGE_WITHLABELS_GROUPBY from './MREVRANGE_WITHLABELS_GROUPBY'; import { TIME_SERIES_REDUCERS } from './MRANGE_GROUPBY'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.MREVRANGE_WITHLABELS_GROUPBY', () => { it('transformArguments', () => { assert.deepEqual( - MREVRANGE_WITHLABELS_GROUPBY.transformArguments('-', '+', 'label=value', { + parseArgs(MREVRANGE_WITHLABELS_GROUPBY, '-', '+', 'label=value', { label: 'label', REDUCE: TIME_SERIES_REDUCERS.AVG }, { diff --git a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.ts b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.ts index b3d49643fd..ed43d0eae6 100644 --- a/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.ts +++ b/packages/time-series/lib/commands/MREVRANGE_WITHLABELS_GROUPBY.ts @@ -1,9 +1,8 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import MRANGE_WITHLABELS_GROUPBY, { createMRangeWithLabelsGroupByTransformArguments } from './MRANGE_WITHLABELS_GROUPBY'; export default { - FIRST_KEY_INDEX: MRANGE_WITHLABELS_GROUPBY.FIRST_KEY_INDEX, IS_READ_ONLY: MRANGE_WITHLABELS_GROUPBY.IS_READ_ONLY, - transformArguments: createMRangeWithLabelsGroupByTransformArguments('TS.MREVRANGE'), + parseCommand: createMRangeWithLabelsGroupByTransformArguments('TS.MREVRANGE'), transformReply: MRANGE_WITHLABELS_GROUPBY.transformReply, } as const satisfies Command; diff --git a/packages/time-series/lib/commands/QUERYINDEX.spec.ts b/packages/time-series/lib/commands/QUERYINDEX.spec.ts index 74f201bb74..2f3f5617fb 100644 --- a/packages/time-series/lib/commands/QUERYINDEX.spec.ts +++ b/packages/time-series/lib/commands/QUERYINDEX.spec.ts @@ -1,19 +1,20 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import QUERYINDEX from './QUERYINDEX'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.QUERYINDEX', () => { describe('transformArguments', () => { it('single filter', () => { assert.deepEqual( - QUERYINDEX.transformArguments('*'), + parseArgs(QUERYINDEX, '*'), ['TS.QUERYINDEX', '*'] ); }); it('multiple filters', () => { assert.deepEqual( - QUERYINDEX.transformArguments(['a=1', 'b=2']), + parseArgs(QUERYINDEX, ['a=1', 'b=2']), ['TS.QUERYINDEX', 'a=1', 'b=2'] ); }); diff --git a/packages/time-series/lib/commands/QUERYINDEX.ts b/packages/time-series/lib/commands/QUERYINDEX.ts index 86c2a3c5a7..6962580197 100644 --- a/packages/time-series/lib/commands/QUERYINDEX.ts +++ b/packages/time-series/lib/commands/QUERYINDEX.ts @@ -1,11 +1,13 @@ -import { ArrayReply, BlobStringReply, SetReply, Command } from '@redis/client/dist/lib/RESP/types'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { ArrayReply, BlobStringReply, SetReply, Command } from '@redis/client/lib/RESP/types'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; export default { - FIRST_KEY_INDEX: undefined, + NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, - transformArguments(filter: RedisVariadicArgument) { - return pushVariadicArguments(['TS.QUERYINDEX'], filter); + parseCommand(parser: CommandParser, filter: RedisVariadicArgument) { + parser.push('TS.QUERYINDEX'); + parser.pushVariadic(filter); }, transformReply: { 2: undefined as unknown as () => ArrayReply, diff --git a/packages/time-series/lib/commands/RANGE.spec.ts b/packages/time-series/lib/commands/RANGE.spec.ts index bc5d38d740..2d20b455fc 100644 --- a/packages/time-series/lib/commands/RANGE.spec.ts +++ b/packages/time-series/lib/commands/RANGE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import RANGE from './RANGE'; import { TIME_SERIES_AGGREGATION_TYPE } from './CREATERULE'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.RANGE', () => { it('transformArguments', () => { assert.deepEqual( - RANGE.transformArguments('key', '-', '+', { + parseArgs(RANGE, 'key', '-', '+', { FILTER_BY_TS: [0], FILTER_BY_VALUE: { min: 1, diff --git a/packages/time-series/lib/commands/RANGE.ts b/packages/time-series/lib/commands/RANGE.ts index 084073fefe..ef4c79fe60 100644 --- a/packages/time-series/lib/commands/RANGE.ts +++ b/packages/time-series/lib/commands/RANGE.ts @@ -1,7 +1,8 @@ -import { CommandArguments, RedisArgument, Command } from '@redis/client/dist/lib/RESP/types'; +import { CommandParser } from '@redis/client/lib/client/parser'; +import { RedisArgument, Command } from '@redis/client/lib/RESP/types'; import { Timestamp, transformTimestampArgument, SamplesRawReply, transformSamplesReply } from '.'; import { TimeSeriesAggregationType } from './CREATERULE'; -import { Resp2Reply } from '@redis/client/dist/lib/RESP/types'; +import { Resp2Reply } from '@redis/client/lib/RESP/types'; export const TIME_SERIES_BUCKET_TIMESTAMP = { LOW: '-', @@ -29,30 +30,30 @@ export interface TsRangeOptions { }; } -export function pushRangeArguments( - args: CommandArguments, +export function parseRangeArguments( + parser: CommandParser, fromTimestamp: Timestamp, toTimestamp: Timestamp, options?: TsRangeOptions ) { - args.push( + parser.push( transformTimestampArgument(fromTimestamp), transformTimestampArgument(toTimestamp) ); if (options?.LATEST) { - args.push('LATEST'); + parser.push('LATEST'); } if (options?.FILTER_BY_TS) { - args.push('FILTER_BY_TS'); + parser.push('FILTER_BY_TS'); for (const timestamp of options.FILTER_BY_TS) { - args.push(transformTimestampArgument(timestamp)); + parser.push(transformTimestampArgument(timestamp)); } } if (options?.FILTER_BY_VALUE) { - args.push( + parser.push( 'FILTER_BY_VALUE', options.FILTER_BY_VALUE.min.toString(), options.FILTER_BY_VALUE.max.toString() @@ -60,54 +61,52 @@ export function pushRangeArguments( } if (options?.COUNT !== undefined) { - args.push('COUNT', options.COUNT.toString()); + parser.push('COUNT', options.COUNT.toString()); } if (options?.AGGREGATION) { if (options?.ALIGN !== undefined) { - args.push('ALIGN', transformTimestampArgument(options.ALIGN)); + parser.push('ALIGN', transformTimestampArgument(options.ALIGN)); } - args.push( + parser.push( 'AGGREGATION', options.AGGREGATION.type, transformTimestampArgument(options.AGGREGATION.timeBucket) ); if (options.AGGREGATION.BUCKETTIMESTAMP) { - args.push( + parser.push( 'BUCKETTIMESTAMP', options.AGGREGATION.BUCKETTIMESTAMP ); } if (options.AGGREGATION.EMPTY) { - args.push('EMPTY'); + parser.push('EMPTY'); } } - - return args; } export function transformRangeArguments( - command: RedisArgument, + parser: CommandParser, key: RedisArgument, fromTimestamp: Timestamp, toTimestamp: Timestamp, options?: TsRangeOptions ) { - return pushRangeArguments( - [command, key], - fromTimestamp, - toTimestamp, - options - ); + parser.pushKey(key); + parseRangeArguments(parser, fromTimestamp, toTimestamp, options); } export default { - FIRST_KEY_INDEX: 1, IS_READ_ONLY: true, - transformArguments: transformRangeArguments.bind(undefined, 'TS.RANGE'), + parseCommand(...args: Parameters) { + const parser = args[0]; + + parser.push('TS.RANGE'); + transformRangeArguments(...args); + }, transformReply: { 2(reply: Resp2Reply) { return transformSamplesReply[2](reply); diff --git a/packages/time-series/lib/commands/REVRANGE.spec.ts b/packages/time-series/lib/commands/REVRANGE.spec.ts index c371e8306b..a4c6aa2c0d 100644 --- a/packages/time-series/lib/commands/REVRANGE.spec.ts +++ b/packages/time-series/lib/commands/REVRANGE.spec.ts @@ -2,11 +2,12 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; import REVRANGE from './REVRANGE'; import { TIME_SERIES_AGGREGATION_TYPE } from '../index'; +import { parseArgs } from '@redis/client/lib/commands/generic-transformers'; describe('TS.REVRANGE', () => { it('transformArguments', () => { assert.deepEqual( - REVRANGE.transformArguments('key', '-', '+', { + parseArgs(REVRANGE, 'key', '-', '+', { FILTER_BY_TS: [0], FILTER_BY_VALUE: { min: 1, diff --git a/packages/time-series/lib/commands/REVRANGE.ts b/packages/time-series/lib/commands/REVRANGE.ts index 1097223080..24a31a785a 100644 --- a/packages/time-series/lib/commands/REVRANGE.ts +++ b/packages/time-series/lib/commands/REVRANGE.ts @@ -1,9 +1,13 @@ -import { Command } from '@redis/client/dist/lib/RESP/types'; +import { Command } from '@redis/client/lib/RESP/types'; import RANGE, { transformRangeArguments } from './RANGE'; export default { - FIRST_KEY_INDEX: RANGE.FIRST_KEY_INDEX, IS_READ_ONLY: RANGE.IS_READ_ONLY, - transformArguments: transformRangeArguments.bind(undefined, 'TS.REVRANGE'), + parseCommand(...args: Parameters) { + const parser = args[0]; + + parser.push('TS.REVRANGE'); + transformRangeArguments(...args); + }, transformReply: RANGE.transformReply } as const satisfies Command; diff --git a/packages/time-series/lib/commands/index.spec.ts b/packages/time-series/lib/commands/index.spec.ts index ff7f4afad6..5b28708152 100644 --- a/packages/time-series/lib/commands/index.spec.ts +++ b/packages/time-series/lib/commands/index.spec.ts @@ -1,4 +1,4 @@ -// import { RedisCommandArguments } from '@redis/client/dist/lib/commands'; +// import { RedisCommandArguments } from '@redis/client/lib/commands'; // import { strict as assert } from 'node:assert'; // import { // transformTimestampArgument, diff --git a/packages/time-series/lib/commands/index.ts b/packages/time-series/lib/commands/index.ts index 5b9d97b656..e0389a60a2 100644 --- a/packages/time-series/lib/commands/index.ts +++ b/packages/time-series/lib/commands/index.ts @@ -1,4 +1,4 @@ -import type { DoubleReply, NumberReply, RedisArgument, RedisCommands, TuplesReply, UnwrapReply, Resp2Reply, ArrayReply, BlobStringReply, MapReply, NullReply, TypeMapping, ReplyUnion, RespType } from '@redis/client/lib/RESP/types'; +import type { DoubleReply, NumberReply, RedisCommands, TuplesReply, UnwrapReply, Resp2Reply, ArrayReply, BlobStringReply, MapReply, NullReply, TypeMapping, ReplyUnion, RespType } from '@redis/client/lib/RESP/types'; import ADD, { TsIgnoreOptions } from './ADD'; import ALTER from './ALTER'; import CREATE from './CREATE'; @@ -29,7 +29,8 @@ import MREVRANGE from './MREVRANGE'; import QUERYINDEX from './QUERYINDEX'; import RANGE from './RANGE'; import REVRANGE from './REVRANGE'; -import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/lib/commands/generic-transformers'; +import { RedisVariadicArgument } from '@redis/client/lib/commands/generic-transformers'; +import { CommandParser } from '@redis/client/lib/client/parser'; import { RESP_TYPES } from '@redis/client/lib/RESP/decoder'; export default { @@ -95,15 +96,15 @@ export default { revRange: REVRANGE } as const satisfies RedisCommands; -export function pushIgnoreArgument(args: Array, ignore?: TsIgnoreOptions) { +export function parseIgnoreArgument(parser: CommandParser, ignore?: TsIgnoreOptions) { if (ignore !== undefined) { - args.push('IGNORE', ignore.maxTimeDiff.toString(), ignore.maxValDiff.toString()); + parser.push('IGNORE', ignore.maxTimeDiff.toString(), ignore.maxValDiff.toString()); } } -export function pushRetentionArgument(args: Array, retention?: number) { +export function parseRetentionArgument(parser: CommandParser, retention?: number) { if (retention !== undefined) { - args.push('RETENTION', retention.toString()); + parser.push('RETENTION', retention.toString()); } } @@ -114,15 +115,15 @@ export const TIME_SERIES_ENCODING = { export type TimeSeriesEncoding = typeof TIME_SERIES_ENCODING[keyof typeof TIME_SERIES_ENCODING]; -export function pushEncodingArgument(args: Array, encoding?: TimeSeriesEncoding) { +export function parseEncodingArgument(parser: CommandParser, encoding?: TimeSeriesEncoding) { if (encoding !== undefined) { - args.push('ENCODING', encoding); + parser.push('ENCODING', encoding); } } -export function pushChunkSizeArgument(args: Array, chunkSize?: number) { +export function parseChunkSizeArgument(parser: CommandParser, chunkSize?: number) { if (chunkSize !== undefined) { - args.push('CHUNK_SIZE', chunkSize.toString()); + parser.push('CHUNK_SIZE', chunkSize.toString()); } } @@ -137,9 +138,9 @@ export const TIME_SERIES_DUPLICATE_POLICIES = { export type TimeSeriesDuplicatePolicies = typeof TIME_SERIES_DUPLICATE_POLICIES[keyof typeof TIME_SERIES_DUPLICATE_POLICIES]; -export function pushDuplicatePolicy(args: Array, duplicatePolicy?: TimeSeriesDuplicatePolicies) { +export function parseDuplicatePolicy(parser: CommandParser, duplicatePolicy?: TimeSeriesDuplicatePolicies) { if (duplicatePolicy !== undefined) { - args.push('DUPLICATE_POLICY', duplicatePolicy); + parser.push('DUPLICATE_POLICY', duplicatePolicy); } } @@ -159,16 +160,14 @@ export type Labels = { [label: string]: string; }; -export function pushLabelsArgument(args: Array, labels?: Labels) { +export function parseLabelsArgument(parser: CommandParser, labels?: Labels) { if (labels) { - args.push('LABELS'); + parser.push('LABELS'); for (const [label, value] of Object.entries(labels)) { - args.push(label, value); + parser.push(label, value); } } - - return args; } export type SampleRawReply = TuplesReply<[timestamp: NumberReply, value: DoubleReply]>; @@ -269,12 +268,12 @@ export function resp3MapToValue< return reply as never; } -export function pushSelectedLabelsArguments( - args: Array, +export function parseSelectedLabelsArguments( + parser: CommandParser, selectedLabels: RedisVariadicArgument ) { - args.push('SELECTED_LABELS'); - return pushVariadicArguments(args, selectedLabels); + parser.push('SELECTED_LABELS'); + parser.pushVariadic(selectedLabels); } export type RawLabelValue = BlobStringReply | NullReply;