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;