You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-04 15:02:09 +03:00
WIP
This commit is contained in:
567
package-lock.json
generated
567
package-lock.json
generated
@@ -10,15 +10,14 @@
|
|||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@tsconfig/node18": "^18.2.2",
|
|
||||||
"@types/mocha": "^10.0.3",
|
"@types/mocha": "^10.0.3",
|
||||||
|
"@types/node": "^20.8.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||||
"@typescript-eslint/parser": "^6.9.0",
|
"@typescript-eslint/parser": "^6.9.0",
|
||||||
"gh-pages": "^6.0.0",
|
"gh-pages": "^6.0.0",
|
||||||
"mocha": "^10.2.0",
|
"mocha": "^10.2.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"source-map-support": "^0.5.21",
|
"tsx": "^3.14.0",
|
||||||
"ts-node": "^10.9.1",
|
|
||||||
"typedoc": "^0.25.2",
|
"typedoc": "^0.25.2",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
@@ -509,26 +508,356 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cspotcode/source-map-support": {
|
"node_modules/@esbuild/android-arm": {
|
||||||
"version": "0.8.1",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
|
||||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"optional": true,
|
||||||
"@jridgewell/trace-mapping": "0.3.9"
|
"os": [
|
||||||
},
|
"android"
|
||||||
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@esbuild/android-arm64": {
|
||||||
"version": "0.3.9",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"optional": true,
|
||||||
"@jridgewell/resolve-uri": "^3.0.3",
|
"os": [
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-x64": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
@@ -903,36 +1232,6 @@
|
|||||||
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
|
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node10": {
|
|
||||||
"version": "1.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
|
||||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node12": {
|
|
||||||
"version": "1.0.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
|
||||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node14": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node16": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node18": {
|
|
||||||
"version": "18.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.2.tgz",
|
|
||||||
"integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.14",
|
"version": "7.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
|
||||||
@@ -946,13 +1245,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.8.6",
|
"version": "20.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz",
|
||||||
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
|
"integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.25.1"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
@@ -1185,6 +1483,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -1202,15 +1501,6 @@
|
|||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn-walk": {
|
|
||||||
"version": "8.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
|
||||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/aggregate-error": {
|
"node_modules/aggregate-error": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||||
@@ -1311,12 +1601,6 @@
|
|||||||
"integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
|
"integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/arg": {
|
|
||||||
"version": "4.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
|
||||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
@@ -1610,12 +1894,6 @@
|
|||||||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/create-require": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@@ -1736,6 +2014,43 @@
|
|||||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.18.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||||
|
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/android-arm": "0.18.20",
|
||||||
|
"@esbuild/android-arm64": "0.18.20",
|
||||||
|
"@esbuild/android-x64": "0.18.20",
|
||||||
|
"@esbuild/darwin-arm64": "0.18.20",
|
||||||
|
"@esbuild/darwin-x64": "0.18.20",
|
||||||
|
"@esbuild/freebsd-arm64": "0.18.20",
|
||||||
|
"@esbuild/freebsd-x64": "0.18.20",
|
||||||
|
"@esbuild/linux-arm": "0.18.20",
|
||||||
|
"@esbuild/linux-arm64": "0.18.20",
|
||||||
|
"@esbuild/linux-ia32": "0.18.20",
|
||||||
|
"@esbuild/linux-loong64": "0.18.20",
|
||||||
|
"@esbuild/linux-mips64el": "0.18.20",
|
||||||
|
"@esbuild/linux-ppc64": "0.18.20",
|
||||||
|
"@esbuild/linux-riscv64": "0.18.20",
|
||||||
|
"@esbuild/linux-s390x": "0.18.20",
|
||||||
|
"@esbuild/linux-x64": "0.18.20",
|
||||||
|
"@esbuild/netbsd-x64": "0.18.20",
|
||||||
|
"@esbuild/openbsd-x64": "0.18.20",
|
||||||
|
"@esbuild/sunos-x64": "0.18.20",
|
||||||
|
"@esbuild/win32-arm64": "0.18.20",
|
||||||
|
"@esbuild/win32-ia32": "0.18.20",
|
||||||
|
"@esbuild/win32-x64": "0.18.20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||||
@@ -2193,6 +2508,18 @@
|
|||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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,
|
||||||
|
"dependencies": {
|
||||||
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gh-pages": {
|
"node_modules/gh-pages": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.0.0.tgz",
|
||||||
@@ -2872,12 +3199,6 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/make-error": {
|
|
||||||
"version": "1.3.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
|
||||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||||
@@ -3633,6 +3954,15 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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,
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reusify": {
|
"node_modules/reusify": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||||
@@ -4021,56 +4351,21 @@
|
|||||||
"typescript": ">=4.2.0"
|
"typescript": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-node": {
|
"node_modules/tsx": {
|
||||||
"version": "10.9.1",
|
"version": "3.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/tsx/-/tsx-3.14.0.tgz",
|
||||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
"integrity": "sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cspotcode/source-map-support": "^0.8.0",
|
"esbuild": "~0.18.20",
|
||||||
"@tsconfig/node10": "^1.0.7",
|
"get-tsconfig": "^4.7.2",
|
||||||
"@tsconfig/node12": "^1.0.7",
|
"source-map-support": "^0.5.21"
|
||||||
"@tsconfig/node14": "^1.0.0",
|
|
||||||
"@tsconfig/node16": "^1.0.2",
|
|
||||||
"acorn": "^8.4.1",
|
|
||||||
"acorn-walk": "^8.1.1",
|
|
||||||
"arg": "^4.1.0",
|
|
||||||
"create-require": "^1.1.0",
|
|
||||||
"diff": "^4.0.1",
|
|
||||||
"make-error": "^1.1.1",
|
|
||||||
"v8-compile-cache-lib": "^3.0.1",
|
|
||||||
"yn": "3.1.1"
|
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"ts-node": "dist/bin.js",
|
"tsx": "dist/cli.mjs"
|
||||||
"ts-node-cwd": "dist/bin-cwd.js",
|
|
||||||
"ts-node-esm": "dist/bin-esm.js",
|
|
||||||
"ts-node-script": "dist/bin-script.js",
|
|
||||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
|
||||||
"ts-script": "dist/bin-script-deprecated.js"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core": ">=1.2.50",
|
"fsevents": "~2.3.3"
|
||||||
"@swc/wasm": ">=1.2.50",
|
|
||||||
"@types/node": "*",
|
|
||||||
"typescript": ">=2.7"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@swc/core": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@swc/wasm": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ts-node/node_modules/diff": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.3.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
@@ -4176,11 +4471,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.25.3",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@@ -4240,12 +4534,6 @@
|
|||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/v8-compile-cache-lib": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/vscode-oniguruma": {
|
"node_modules/vscode-oniguruma": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||||
@@ -4401,15 +4689,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yn": {
|
|
||||||
"version": "3.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
|
||||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
11
package.json
11
package.json
@@ -12,16 +12,15 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@tsconfig/node18": "^18.2.2",
|
|
||||||
"@types/mocha": "^10.0.3",
|
"@types/mocha": "^10.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
"@types/node": "^20.8.10",
|
||||||
"@typescript-eslint/parser": "^6.9.0",
|
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
||||||
|
"@typescript-eslint/parser": "^6.9.1",
|
||||||
"gh-pages": "^6.0.0",
|
"gh-pages": "^6.0.0",
|
||||||
"mocha": "^10.2.0",
|
"mocha": "^10.2.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"source-map-support": "^0.5.21",
|
"tsx": "^3.14.0",
|
||||||
"ts-node": "^10.9.1",
|
"typedoc": "^0.25.3",
|
||||||
"typedoc": "^0.25.2",
|
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
|
||||||
|
|
||||||
export interface BfReserveOptions {
|
export interface BfReserveOptions {
|
||||||
EXPANSION?: number;
|
EXPANSION?: number;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"!dist/tsconfig.tsbuildinfo"
|
"!dist/tsconfig.tsbuildinfo"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "*"
|
"@redis/client": "*"
|
||||||
|
@@ -210,11 +210,6 @@ export type ReplyWithTypeMapping<
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
type a = ReplyWithTypeMapping<
|
|
||||||
ArrayReply<TuplesReply<[BlobStringReply | NullReply]>>,
|
|
||||||
{}
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type TransformReply = (this: void, reply: any, preserve?: any) => any; // TODO;
|
export type TransformReply = (this: void, reply: any, preserve?: any) => any; // TODO;
|
||||||
|
|
||||||
export type RedisArgument = string | Buffer;
|
export type RedisArgument = string | Buffer;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, Command, CommandArguments, ReplyUnion } from '../RESP/types';
|
import { RedisModules, RedisFunctions, RedisScripts, RespVersions, Command, CommandArguments, ReplyUnion } from '../RESP/types';
|
||||||
import { RedisClientType } from '.';
|
import { RedisClientType } from '.';
|
||||||
import { getTransformReply } from '../commander';
|
import { getTransformReply } from '../commander';
|
||||||
import { ErrorReply } from '../errors';
|
import { ErrorReply } from '../errors';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import COMMANDS from '../commands';
|
import COMMANDS from '../commands';
|
||||||
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../multi-command';
|
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../multi-command';
|
||||||
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping, ReplyUnion } from '../RESP/types';
|
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
|
||||||
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
|
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
|
||||||
import { RedisClientType } from '.';
|
import { RedisClientType } from '.';
|
||||||
|
|
||||||
|
@@ -1,16 +1,10 @@
|
|||||||
import { RedisClusterClientOptions, RedisClusterOptions } from '.';
|
import { RedisClusterClientOptions, RedisClusterOptions } from '.';
|
||||||
import { RootNodesUnavailableError } from '../errors';
|
import { RootNodesUnavailableError } from '../errors';
|
||||||
import RedisClient, { RedisClientOptions, RedisClientType } from '../client';
|
import RedisClient, { RedisClientOptions, RedisClientType } from '../client';
|
||||||
import { types } from 'node:util';
|
|
||||||
import { EventEmitter } from 'node:stream';
|
import { EventEmitter } from 'node:stream';
|
||||||
import { ChannelListeners, PubSubType, PubSubTypeListeners } from '../client/pub-sub';
|
import { ChannelListeners, PubSubType, PubSubTypeListeners } from '../client/pub-sub';
|
||||||
import { RedisArgument, RedisFunctions, RedisModules, RedisScripts, RespVersions, TypeMapping } from '../RESP/types';
|
import { RedisArgument, RedisFunctions, RedisModules, RedisScripts, RespVersions, TypeMapping } from '../RESP/types';
|
||||||
|
import calculateSlot from 'cluster-key-slot';
|
||||||
// TODO: ?!
|
|
||||||
// We need to use 'require', because it's not possible with Typescript to import
|
|
||||||
// function that are exported as 'module.exports = function`, without esModuleInterop
|
|
||||||
// set to true.
|
|
||||||
const calculateSlot = require('cluster-key-slot');
|
|
||||||
|
|
||||||
interface NodeAddress {
|
interface NodeAddress {
|
||||||
host: string;
|
host: string;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import COMMANDS from '../commands';
|
import COMMANDS from '../commands';
|
||||||
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../multi-command';
|
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../multi-command';
|
||||||
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping, ReplyUnion, RedisArgument } from '../RESP/types';
|
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 { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
|
||||||
import RedisCluster, { RedisClusterType } from '.';
|
import RedisCluster, { RedisClusterType } from '.';
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { strict as assert } from 'node:assert';
|
import { strict as assert } from 'node:assert';
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import CLIENT_TRACKINGINFO from './CLIENT_TRACKINGINFO';
|
import CLIENT_TRACKINGINFO from './CLIENT_TRACKINGINFO';
|
||||||
import { RESP_TYPES } from '../RESP/decoder';
|
|
||||||
|
|
||||||
describe('CLIENT TRACKINGINFO', () => {
|
describe('CLIENT TRACKINGINFO', () => {
|
||||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../RESP/types';
|
import { Command } from '../RESP/types';
|
||||||
import EVAL, { EvalOptions, transformEvalArguments } from './EVAL';
|
import EVAL, { transformEvalArguments } from './EVAL';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
|
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../RESP/types';
|
import { Command } from '../RESP/types';
|
||||||
import EVAL, { EvalOptions, transformEvalArguments } from './EVAL';
|
import EVAL, { transformEvalArguments } from './EVAL';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
|
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NullReply, SetReply, UnwrapReply, Resp2Reply, CommandArguments, Command, ReplyWithTypeMapping } from '../RESP/types';
|
import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, NullReply, SetReply, UnwrapReply, Resp2Reply, CommandArguments, Command } from '../RESP/types';
|
||||||
|
|
||||||
export interface FunctionListOptions {
|
export interface FunctionListOptions {
|
||||||
LIBRARYNAME?: RedisArgument;
|
LIBRARYNAME?: RedisArgument;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
import { RedisArgument, CommandArguments, Command } from '../RESP/types';
|
||||||
import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
|
import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
|
||||||
import { GeoSearchOptions, GeoUnits, pushGeoSearchOptions } from './GEOSEARCH';
|
import { GeoSearchOptions, GeoUnits, pushGeoSearchOptions } from './GEOSEARCH';
|
||||||
import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH';
|
import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH';
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types';
|
import { TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, ArrayReply, UnwrapReply, Command } from '../RESP/types';
|
||||||
|
|
||||||
export type MemoryStatsReply = TuplesToMapReply<[
|
export type MemoryStatsReply = TuplesToMapReply<[
|
||||||
[BlobStringReply<'peak.allocated'>, NumberReply],
|
[BlobStringReply<'peak.allocated'>, NumberReply],
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
||||||
import { pushVariadicArguments } from './generic-transformers';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FIRST_KEY_INDEX: undefined,
|
FIRST_KEY_INDEX: undefined,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
import { SimpleStringReply, Command } from '../RESP/types';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FIRST_KEY_INDEX: undefined,
|
FIRST_KEY_INDEX: undefined,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, DoubleReply, Command } from '../RESP/types';
|
import { RedisArgument, Command } from '../RESP/types';
|
||||||
import { transformDoubleArgument, transformDoubleReply } from './generic-transformers';
|
import { transformDoubleArgument, transformDoubleReply } from './generic-transformers';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
||||||
import { ScanCommonOptions, pushScanArguments } from './SCAN';
|
import { ScanCommonOptions, pushScanArguments } from './SCAN';
|
||||||
import { SortedSetMember, transformDoubleReply, transformSortedSetReply } from './generic-transformers';
|
import { transformSortedSetReply } from './generic-transformers';
|
||||||
|
|
||||||
export interface HScanEntry {
|
export interface HScanEntry {
|
||||||
field: BlobStringReply;
|
field: BlobStringReply;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { UnwrapReply, ArrayReply, BlobStringReply, BooleanReply, CommandArguments, DoubleReply, MapReply, NullReply, NumberReply, RedisArgument, TuplesReply, RespType } from '../RESP/types';
|
import { UnwrapReply, ArrayReply, BlobStringReply, BooleanReply, CommandArguments, DoubleReply, NullReply, NumberReply, RedisArgument, TuplesReply } from '../RESP/types';
|
||||||
|
|
||||||
export function isNullReply(reply: unknown): reply is NullReply {
|
export function isNullReply(reply: unknown): reply is NullReply {
|
||||||
return reply === null;
|
return reply === null;
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"!dist/tsconfig.tsbuildinfo"
|
"!dist/tsconfig.tsbuildinfo"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cluster-key-slot": "1.1.2",
|
"cluster-key-slot": "1.1.2",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisClientType } from '@redis/client/dist/lib/client/index';
|
import { RedisClientType } from '@redis/client';
|
||||||
import { RedisArgument, RedisFunctions, RedisScripts } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, RedisFunctions, RedisScripts } from '@redis/client/dist/lib/RESP/types';
|
||||||
import QUERY, { QueryOptions } from './commands/QUERY';
|
import QUERY, { QueryOptions } from './commands/QUERY';
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ type GraphReply<T> = {
|
|||||||
type GraphClientType = RedisClientType<{
|
type GraphClientType = RedisClientType<{
|
||||||
graph: {
|
graph: {
|
||||||
query: typeof QUERY,
|
query: typeof QUERY,
|
||||||
roQuery: typeof import('./commands/RO_QUERY').default
|
roQuery: typeof import('./commands/RO_QUERY.js').default
|
||||||
}
|
}
|
||||||
}, RedisFunctions, RedisScripts>;
|
}, RedisFunctions, RedisScripts>;
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"!dist/tsconfig.tsbuildinfo"
|
"!dist/tsconfig.tsbuildinfo"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "*"
|
"@redis/client": "*"
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { RedisArgument, NumberReply, ArrayReply, Command } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export interface JsonDebugMemoryOptions {
|
export interface JsonDebugMemoryOptions {
|
||||||
path?: RedisArgument;
|
path?: RedisArgument;
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
"dist/"
|
"dist/"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "*"
|
"@redis/client": "*"
|
||||||
|
@@ -1,509 +1,515 @@
|
|||||||
import { strict as assert } from 'node:assert';
|
import { strict as assert } from 'node:assert';
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { AggregateGroupByReducers, AggregateSteps, transformArguments } from './AGGREGATE';
|
import AGGREGATE from './AGGREGATE';
|
||||||
import { SchemaFieldTypes } from '.';
|
// import { SchemaFieldTypes } from '.';
|
||||||
|
|
||||||
describe('AGGREGATE', () => {
|
describe('AGGREGATE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without options', () => {
|
it('without options', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*'),
|
||||||
|
['FT.AGGREGATE', 'index', '*']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with VERBATIM', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
VERBATIM: true
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'VERBATIM']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with LOAD', () => {
|
||||||
|
describe('single', () => {
|
||||||
|
describe('without alias', () => {
|
||||||
|
it('string', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*'),
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
['FT.AGGREGATE', 'index', '*']
|
LOAD: '@property'
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('{ identifier: string }', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
LOAD: {
|
||||||
|
identifier: '@property'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with VERBATIM', () => {
|
it('with alias', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*', { VERBATIM: true }),
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
['FT.AGGREGATE', 'index', '*', 'VERBATIM']
|
LOAD: {
|
||||||
);
|
identifier: '@property',
|
||||||
|
AS: 'alias'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'LOAD', '3', '@property', 'AS', 'alias']
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('with LOAD', () => {
|
it('multiple', () => {
|
||||||
describe('single', () => {
|
assert.deepEqual(
|
||||||
describe('without alias', () => {
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
it('string', () => {
|
LOAD: ['@1', '@2']
|
||||||
assert.deepEqual(
|
}),
|
||||||
transformArguments('index', '*', { LOAD: '@property' }),
|
['FT.AGGREGATE', 'index', '*', 'LOAD', '2', '@1', '@2']
|
||||||
['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
|
);
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('{ identifier: string }', () => {
|
describe('with STEPS', () => {
|
||||||
assert.deepEqual(
|
describe('GROUPBY', () => {
|
||||||
transformArguments('index', '*', {
|
describe('COUNT', () => {
|
||||||
LOAD: {
|
describe('without properties', () => {
|
||||||
identifier: '@property'
|
it('without alias', () => {
|
||||||
}
|
assert.deepEqual(
|
||||||
}),
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
|
STEPS: [{
|
||||||
);
|
type: 'GROUPBY',
|
||||||
});
|
REDUCE: {
|
||||||
});
|
type: 'COUNT'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('with alias', () => {
|
it('with alias', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*', {
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
LOAD: {
|
STEPS: [{
|
||||||
identifier: '@property',
|
type: 'GROUPBY',
|
||||||
AS: 'alias'
|
REDUCE: {
|
||||||
}
|
type: 'COUNT',
|
||||||
}),
|
AS: 'count'
|
||||||
['FT.AGGREGATE', 'index', '*', 'LOAD', '3', '@property', 'AS', 'alias']
|
}
|
||||||
);
|
}]
|
||||||
});
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0', 'AS', 'count']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with properties', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
properties: '@property',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'COUNT'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '1', '@property', 'REDUCE', 'COUNT', '0']
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiple', () => {
|
it('multiple', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*', { LOAD: ['@1', '@2'] }),
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
['FT.AGGREGATE', 'index', '*', 'LOAD', '2', '@1', '@2']
|
STEPS: [{
|
||||||
);
|
type: 'GROUPBY',
|
||||||
});
|
properties: ['@1', '@2'],
|
||||||
});
|
REDUCE: {
|
||||||
|
type: 'COUNT'
|
||||||
describe('with STEPS', () => {
|
|
||||||
describe('GROUPBY', () => {
|
|
||||||
describe('COUNT', () => {
|
|
||||||
describe('without properties', () => {
|
|
||||||
it('without alias', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with alias', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT,
|
|
||||||
AS: 'count'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0', 'AS', 'count']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with properties', () => {
|
|
||||||
it('single', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
properties: '@property',
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '1', '@property', 'REDUCE', 'COUNT', '0']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('multiple', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
properties: ['@1', '@2'],
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '2', '@1', '@2', 'REDUCE', 'COUNT', '0']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('COUNT_DISTINCT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT_DISTINCT,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCT', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('COUNT_DISTINCTISH', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.COUNT_DISTINCTISH,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCTISH', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('SUM', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.SUM,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'SUM', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('MIN', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.MIN,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MIN', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('MAX', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.MAX,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MAX', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('AVG', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.AVG,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'AVG', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('STDDEV', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.STDDEV,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'STDDEV', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('QUANTILE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.QUANTILE,
|
|
||||||
property: '@property',
|
|
||||||
quantile: 0.5
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'QUANTILE', '2', '@property', '0.5']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('TO_LIST', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.TO_LIST,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'TOLIST', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('FIRST_VALUE', () => {
|
|
||||||
it('simple', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.FIRST_VALUE,
|
|
||||||
property: '@property'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '1', '@property']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with BY', () => {
|
|
||||||
describe('without direction', () => {
|
|
||||||
it('string', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.FIRST_VALUE,
|
|
||||||
property: '@property',
|
|
||||||
BY: '@by'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('{ property: string }', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.FIRST_VALUE,
|
|
||||||
property: '@property',
|
|
||||||
BY: {
|
|
||||||
property: '@by'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with direction', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.FIRST_VALUE,
|
|
||||||
property: '@property',
|
|
||||||
BY: {
|
|
||||||
property: '@by',
|
|
||||||
direction: 'ASC'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '4', '@property', 'BY', '@by', 'ASC']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('RANDOM_SAMPLE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.GROUPBY,
|
|
||||||
REDUCE: {
|
|
||||||
type: AggregateGroupByReducers.RANDOM_SAMPLE,
|
|
||||||
property: '@property',
|
|
||||||
sampleSize: 1
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'RANDOM_SAMPLE', '2', '@property', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('SORTBY', () => {
|
|
||||||
it('string', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.SORTBY,
|
|
||||||
BY: '@by'
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Array', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.SORTBY,
|
|
||||||
BY: ['@1', '@2']
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'SORTBY', '2', '@1', '@2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with MAX', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.SORTBY,
|
|
||||||
BY: '@by',
|
|
||||||
MAX: 1
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by', 'MAX', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('APPLY', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.APPLY,
|
|
||||||
expression: '@field + 1',
|
|
||||||
AS: 'as'
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'APPLY', '@field + 1', 'AS', 'as']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('LIMIT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.LIMIT,
|
|
||||||
from: 0,
|
|
||||||
size: 1
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'LIMIT', '0', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('FILTER', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
STEPS: [{
|
|
||||||
type: AggregateSteps.FILTER,
|
|
||||||
expression: '@field != ""'
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'FILTER', '@field != ""']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with PARAMS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', {
|
|
||||||
PARAMS: {
|
|
||||||
param: 'value'
|
|
||||||
}
|
}
|
||||||
|
}]
|
||||||
}),
|
}),
|
||||||
['FT.AGGREGATE', 'index', '*', 'PARAMS', '2', 'param', 'value']
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '2', '@1', '@2', 'REDUCE', 'COUNT', '0']
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with DIALECT', () => {
|
it('COUNT_DISTINCT', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*', {
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
DIALECT: 1
|
STEPS: [{
|
||||||
}),
|
type: 'GROUPBY',
|
||||||
['FT.AGGREGATE', 'index', '*', 'DIALECT', '1']
|
REDUCE: {
|
||||||
);
|
type: 'COUNT_DISTINCT',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCT', '1', '@property']
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with TIMEOUT', () => {
|
it('COUNT_DISTINCTISH', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*', { TIMEOUT: 10 }),
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
['FT.AGGREGATE', 'index', '*', 'TIMEOUT', '10']
|
STEPS: [{
|
||||||
);
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'COUNT_DISTINCTISH',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCTISH', '1', '@property']
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('SUM', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'SUM',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'SUM', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('MIN', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'MIN',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MIN', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('MAX', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'MAX',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MAX', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('AVG', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'AVG',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'AVG', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('STDDEV', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'STDDEV',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'STDDEV', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('QUANTILE', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'QUANTILE',
|
||||||
|
property: '@property',
|
||||||
|
quantile: 0.5
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'QUANTILE', '2', '@property', '0.5']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TOLIST', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'TOLIST',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'TOLIST', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('FIRST_VALUE', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'FIRST_VALUE',
|
||||||
|
property: '@property'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '1', '@property']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with BY', () => {
|
||||||
|
describe('without direction', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'FIRST_VALUE',
|
||||||
|
property: '@property',
|
||||||
|
BY: '@by'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('{ property: string }', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'FIRST_VALUE',
|
||||||
|
property: '@property',
|
||||||
|
BY: {
|
||||||
|
property: '@by'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with direction', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'FIRST_VALUE',
|
||||||
|
property: '@property',
|
||||||
|
BY: {
|
||||||
|
property: '@by',
|
||||||
|
direction: 'ASC'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '4', '@property', 'BY', '@by', 'ASC']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RANDOM_SAMPLE', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'GROUPBY',
|
||||||
|
REDUCE: {
|
||||||
|
type: 'RANDOM_SAMPLE',
|
||||||
|
property: '@property',
|
||||||
|
sampleSize: 1
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'RANDOM_SAMPLE', '2', '@property', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SORTBY', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'SORTBY',
|
||||||
|
BY: '@by'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'SORTBY',
|
||||||
|
BY: ['@1', '@2']
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'SORTBY', '2', '@1', '@2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with MAX', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'SORTBY',
|
||||||
|
BY: '@by',
|
||||||
|
MAX: 1
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by', 'MAX', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('APPLY', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'APPLY',
|
||||||
|
expression: '@field + 1',
|
||||||
|
AS: 'as'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'APPLY', '@field + 1', 'AS', 'as']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('LIMIT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'LIMIT',
|
||||||
|
from: 0,
|
||||||
|
size: 1
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'LIMIT', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('FILTER', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
|
STEPS: [{
|
||||||
|
type: 'FILTER',
|
||||||
|
expression: '@field != ""'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'FILTER', '@field != ""']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.ft.aggregate', async client => {
|
it('with PARAMS', () => {
|
||||||
await Promise.all([
|
assert.deepEqual(
|
||||||
client.ft.create('index', {
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
field: SchemaFieldTypes.NUMERIC
|
PARAMS: {
|
||||||
}),
|
param: 'value'
|
||||||
client.hSet('1', 'field', '1'),
|
}
|
||||||
client.hSet('2', 'field', '2')
|
}),
|
||||||
]);
|
['FT.AGGREGATE', 'index', '*', 'PARAMS', '2', 'param', 'value']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
assert.deepEqual(
|
it('with DIALECT', () => {
|
||||||
await client.ft.aggregate('index', '*', {
|
assert.deepEqual(
|
||||||
STEPS: [{
|
AGGREGATE.transformArguments('index', '*', {
|
||||||
type: AggregateSteps.GROUPBY,
|
DIALECT: 1
|
||||||
REDUCE: [{
|
}),
|
||||||
type: AggregateGroupByReducers.SUM,
|
['FT.AGGREGATE', 'index', '*', 'DIALECT', '1']
|
||||||
property: '@field',
|
);
|
||||||
AS: 'sum'
|
});
|
||||||
}, {
|
|
||||||
type: AggregateGroupByReducers.AVG,
|
it('with TIMEOUT', () => {
|
||||||
property: '@field',
|
assert.deepEqual(
|
||||||
AS: 'avg'
|
AGGREGATE.transformArguments('index', '*', { TIMEOUT: 10 }),
|
||||||
}]
|
['FT.AGGREGATE', 'index', '*', 'TIMEOUT', '10']
|
||||||
}]
|
);
|
||||||
}),
|
});
|
||||||
{
|
});
|
||||||
total: 1,
|
|
||||||
results: [
|
testUtils.testWithClient('client.ft.aggregate', async client => {
|
||||||
Object.create(null, {
|
await Promise.all([
|
||||||
sum: {
|
client.ft.create('index', {
|
||||||
value: '3',
|
field: 'NUMERIC'
|
||||||
configurable: true,
|
}),
|
||||||
enumerable: true
|
client.hSet('1', 'field', '1'),
|
||||||
},
|
client.hSet('2', 'field', '2')
|
||||||
avg: {
|
]);
|
||||||
value: '1.5',
|
|
||||||
configurable: true,
|
assert.deepEqual(
|
||||||
enumerable: true
|
await client.ft.aggregate('index', '*', {
|
||||||
}
|
STEPS: [{
|
||||||
})
|
type: 'GROUPBY',
|
||||||
]
|
REDUCE: [{
|
||||||
|
type: 'SUM',
|
||||||
|
property: '@field',
|
||||||
|
AS: 'sum'
|
||||||
|
}, {
|
||||||
|
type: 'AVG',
|
||||||
|
property: '@field',
|
||||||
|
AS: 'avg'
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
total: 1,
|
||||||
|
results: [
|
||||||
|
Object.create(null, {
|
||||||
|
sum: {
|
||||||
|
value: '3',
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true
|
||||||
|
},
|
||||||
|
avg: {
|
||||||
|
value: '1.5',
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true
|
||||||
}
|
}
|
||||||
);
|
})
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,311 +1,294 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushVariadicArgument, transformTuplesReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RediSearchProperty } from './CREATE';
|
||||||
import { Params, PropertyName, pushArgumentsWithLength, pushParamsArgs, pushSortByArguments, SortByProperty } from '.';
|
import { FtSearchParams, pushParamsArgument } from './SEARCH';
|
||||||
|
import { pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export enum AggregateSteps {
|
type LoadField = RediSearchProperty | {
|
||||||
GROUPBY = 'GROUPBY',
|
identifier: RediSearchProperty;
|
||||||
SORTBY = 'SORTBY',
|
AS?: RedisArgument;
|
||||||
APPLY = 'APPLY',
|
|
||||||
LIMIT = 'LIMIT',
|
|
||||||
FILTER = 'FILTER'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AggregateStep<T extends AggregateSteps> {
|
export const FT_AGGREGATE_STEPS = {
|
||||||
type: T;
|
GROUPBY: 'GROUPBY',
|
||||||
|
SORTBY: 'SORTBY',
|
||||||
|
APPLY: 'APPLY',
|
||||||
|
LIMIT: 'LIMIT',
|
||||||
|
FILTER: 'FILTER'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
type FT_AGGREGATE_STEPS = typeof FT_AGGREGATE_STEPS;
|
||||||
|
|
||||||
|
export type FtAggregateStep = FT_AGGREGATE_STEPS[keyof FT_AGGREGATE_STEPS];
|
||||||
|
|
||||||
|
interface AggregateStep<T extends FtAggregateStep> {
|
||||||
|
type: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AggregateGroupByReducers {
|
export const FT_AGGREGATE_GROUP_BY_REDUCERS = {
|
||||||
COUNT = 'COUNT',
|
COUNT: 'COUNT',
|
||||||
COUNT_DISTINCT = 'COUNT_DISTINCT',
|
COUNT_DISTINCT: 'COUNT_DISTINCT',
|
||||||
COUNT_DISTINCTISH = 'COUNT_DISTINCTISH',
|
COUNT_DISTINCTISH: 'COUNT_DISTINCTISH',
|
||||||
SUM = 'SUM',
|
SUM: 'SUM',
|
||||||
MIN = 'MIN',
|
MIN: 'MIN',
|
||||||
MAX = 'MAX',
|
MAX: 'MAX',
|
||||||
AVG = 'AVG',
|
AVG: 'AVG',
|
||||||
STDDEV = 'STDDEV',
|
STDDEV: 'STDDEV',
|
||||||
QUANTILE = 'QUANTILE',
|
QUANTILE: 'QUANTILE',
|
||||||
TOLIST = 'TOLIST',
|
TOLIST: 'TOLIST',
|
||||||
TO_LIST = 'TOLIST',
|
FIRST_VALUE: 'FIRST_VALUE',
|
||||||
FIRST_VALUE = 'FIRST_VALUE',
|
RANDOM_SAMPLE: 'RANDOM_SAMPLE'
|
||||||
RANDOM_SAMPLE = 'RANDOM_SAMPLE'
|
} as const;
|
||||||
|
|
||||||
|
type FT_AGGREGATE_GROUP_BY_REDUCERS = typeof FT_AGGREGATE_GROUP_BY_REDUCERS;
|
||||||
|
|
||||||
|
export type FtAggregateGroupByReducer = FT_AGGREGATE_GROUP_BY_REDUCERS[keyof FT_AGGREGATE_GROUP_BY_REDUCERS];
|
||||||
|
|
||||||
|
interface GroupByReducer<T extends FtAggregateGroupByReducer> {
|
||||||
|
type: T;
|
||||||
|
AS?: RedisArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GroupByReducer<T extends AggregateGroupByReducers> {
|
interface GroupByReducerWithProperty<T extends FtAggregateGroupByReducer> extends GroupByReducer<T> {
|
||||||
type: T;
|
property: RediSearchProperty;
|
||||||
AS?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CountReducer = GroupByReducer<AggregateGroupByReducers.COUNT>;
|
type CountReducer = GroupByReducer<FT_AGGREGATE_GROUP_BY_REDUCERS['COUNT']>;
|
||||||
|
|
||||||
interface CountDistinctReducer extends GroupByReducer<AggregateGroupByReducers.COUNT_DISTINCT> {
|
type CountDistinctReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['COUNT_DISTINCT']>;
|
||||||
property: PropertyName;
|
|
||||||
|
type CountDistinctishReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['COUNT_DISTINCTISH']>;
|
||||||
|
|
||||||
|
type SumReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['SUM']>;
|
||||||
|
|
||||||
|
type MinReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['MIN']>;
|
||||||
|
|
||||||
|
type MaxReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['MAX']>;
|
||||||
|
|
||||||
|
type AvgReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['AVG']>;
|
||||||
|
|
||||||
|
type StdDevReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['STDDEV']>;
|
||||||
|
|
||||||
|
interface QuantileReducer extends GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['QUANTILE']> {
|
||||||
|
quantile: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CountDistinctishReducer extends GroupByReducer<AggregateGroupByReducers.COUNT_DISTINCTISH> {
|
type ToListReducer = GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['TOLIST']>;
|
||||||
property: PropertyName;
|
|
||||||
|
interface FirstValueReducer extends GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['FIRST_VALUE']> {
|
||||||
|
BY?: RediSearchProperty | {
|
||||||
|
property: RediSearchProperty;
|
||||||
|
direction?: 'ASC' | 'DESC';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SumReducer extends GroupByReducer<AggregateGroupByReducers.SUM> {
|
interface RandomSampleReducer extends GroupByReducerWithProperty<FT_AGGREGATE_GROUP_BY_REDUCERS['RANDOM_SAMPLE']> {
|
||||||
property: PropertyName;
|
sampleSize: number;
|
||||||
}
|
|
||||||
|
|
||||||
interface MinReducer extends GroupByReducer<AggregateGroupByReducers.MIN> {
|
|
||||||
property: PropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MaxReducer extends GroupByReducer<AggregateGroupByReducers.MAX> {
|
|
||||||
property: PropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AvgReducer extends GroupByReducer<AggregateGroupByReducers.AVG> {
|
|
||||||
property: PropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StdDevReducer extends GroupByReducer<AggregateGroupByReducers.STDDEV> {
|
|
||||||
property: PropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuantileReducer extends GroupByReducer<AggregateGroupByReducers.QUANTILE> {
|
|
||||||
property: PropertyName;
|
|
||||||
quantile: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ToListReducer extends GroupByReducer<AggregateGroupByReducers.TOLIST> {
|
|
||||||
property: PropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FirstValueReducer extends GroupByReducer<AggregateGroupByReducers.FIRST_VALUE> {
|
|
||||||
property: PropertyName;
|
|
||||||
BY?: PropertyName | {
|
|
||||||
property: PropertyName;
|
|
||||||
direction?: 'ASC' | 'DESC';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RandomSampleReducer extends GroupByReducer<AggregateGroupByReducers.RANDOM_SAMPLE> {
|
|
||||||
property: PropertyName;
|
|
||||||
sampleSize: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupByReducers = CountReducer | CountDistinctReducer | CountDistinctishReducer | SumReducer | MinReducer | MaxReducer | AvgReducer | StdDevReducer | QuantileReducer | ToListReducer | FirstValueReducer | RandomSampleReducer;
|
type GroupByReducers = CountReducer | CountDistinctReducer | CountDistinctishReducer | SumReducer | MinReducer | MaxReducer | AvgReducer | StdDevReducer | QuantileReducer | ToListReducer | FirstValueReducer | RandomSampleReducer;
|
||||||
|
|
||||||
interface GroupByStep extends AggregateStep<AggregateSteps.GROUPBY> {
|
interface GroupByStep extends AggregateStep<FT_AGGREGATE_STEPS['GROUPBY']> {
|
||||||
properties?: PropertyName | Array<PropertyName>;
|
properties?: RediSearchProperty | Array<RediSearchProperty>;
|
||||||
REDUCE: GroupByReducers | Array<GroupByReducers>;
|
REDUCE: GroupByReducers | Array<GroupByReducers>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SortStep extends AggregateStep<AggregateSteps.SORTBY> {
|
type SortByProperty = RedisArgument | {
|
||||||
BY: SortByProperty | Array<SortByProperty>;
|
BY: RediSearchProperty;
|
||||||
MAX?: number;
|
DIRECTION?: 'ASC' | 'DESC';
|
||||||
|
};
|
||||||
|
|
||||||
|
interface SortStep extends AggregateStep<FT_AGGREGATE_STEPS['SORTBY']> {
|
||||||
|
BY: SortByProperty | Array<SortByProperty>;
|
||||||
|
MAX?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApplyStep extends AggregateStep<AggregateSteps.APPLY> {
|
interface ApplyStep extends AggregateStep<FT_AGGREGATE_STEPS['APPLY']> {
|
||||||
expression: string;
|
expression: RedisArgument;
|
||||||
AS: string;
|
AS: RedisArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LimitStep extends AggregateStep<AggregateSteps.LIMIT> {
|
interface LimitStep extends AggregateStep<FT_AGGREGATE_STEPS['LIMIT']> {
|
||||||
from: number;
|
from: number;
|
||||||
size: number;
|
size: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilterStep extends AggregateStep<AggregateSteps.FILTER> {
|
interface FilterStep extends AggregateStep<FT_AGGREGATE_STEPS['FILTER']> {
|
||||||
expression: string;
|
expression: RedisArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoadField = PropertyName | {
|
export interface FtAggregateOptions {
|
||||||
identifier: PropertyName;
|
VERBATIM?: boolean;
|
||||||
AS?: string;
|
LOAD?: LoadField | Array<LoadField>;
|
||||||
|
TIMEOUT?: number;
|
||||||
|
STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>;
|
||||||
|
PARAMS?: FtSearchParams;
|
||||||
|
DIALECT?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AggregateOptions {
|
export default {
|
||||||
VERBATIM?: true;
|
FIRST_KEY_INDEX: undefined,
|
||||||
LOAD?: LoadField | Array<LoadField>;
|
IS_READ_ONLY: false,
|
||||||
STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>;
|
transformArguments(index: RedisArgument, query: RedisArgument, options?: FtAggregateOptions) {
|
||||||
PARAMS?: Params;
|
const args = ['FT.AGGREGATE', index, query];
|
||||||
DIALECT?: number;
|
|
||||||
TIMEOUT?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
|
||||||
|
|
||||||
export function transformArguments(
|
|
||||||
index: string,
|
|
||||||
query: string,
|
|
||||||
options?: AggregateOptions
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushAggregatehOptions(
|
|
||||||
['FT.AGGREGATE', index, query],
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pushAggregatehOptions(
|
|
||||||
args: RedisCommandArguments,
|
|
||||||
options?: AggregateOptions
|
|
||||||
): RedisCommandArguments {
|
|
||||||
if (options?.VERBATIM) {
|
if (options?.VERBATIM) {
|
||||||
args.push('VERBATIM');
|
args.push('VERBATIM');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.LOAD) {
|
if (options?.LOAD) {
|
||||||
args.push('LOAD');
|
const length = args.push('LOAD', '');
|
||||||
pushArgumentsWithLength(args, () => {
|
|
||||||
if (Array.isArray(options.LOAD)) {
|
|
||||||
for (const load of options.LOAD) {
|
|
||||||
pushLoadField(args, load);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pushLoadField(args, options.LOAD!);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.STEPS) {
|
if (Array.isArray(options.LOAD)) {
|
||||||
for (const step of options.STEPS) {
|
for (const load of options.LOAD) {
|
||||||
switch (step.type) {
|
pushLoadField(args, load);
|
||||||
case AggregateSteps.GROUPBY:
|
|
||||||
args.push('GROUPBY');
|
|
||||||
if (!step.properties) {
|
|
||||||
args.push('0');
|
|
||||||
} else {
|
|
||||||
pushVariadicArgument(args, step.properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(step.REDUCE)) {
|
|
||||||
for (const reducer of step.REDUCE) {
|
|
||||||
pushGroupByReducer(args, reducer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pushGroupByReducer(args, step.REDUCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateSteps.SORTBY:
|
|
||||||
pushSortByArguments(args, 'SORTBY', step.BY);
|
|
||||||
|
|
||||||
if (step.MAX) {
|
|
||||||
args.push('MAX', step.MAX.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateSteps.APPLY:
|
|
||||||
args.push('APPLY', step.expression, 'AS', step.AS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateSteps.LIMIT:
|
|
||||||
args.push('LIMIT', step.from.toString(), step.size.toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateSteps.FILTER:
|
|
||||||
args.push('FILTER', step.expression);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
pushLoadField(args, options.LOAD);
|
||||||
|
}
|
||||||
|
|
||||||
pushParamsArgs(args, options?.PARAMS);
|
args[length - 1] = (args.length - length).toString();
|
||||||
|
|
||||||
if (options?.DIALECT) {
|
|
||||||
args.push('DIALECT', options.DIALECT.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.TIMEOUT !== undefined) {
|
if (options?.TIMEOUT !== undefined) {
|
||||||
args.push('TIMEOUT', options.TIMEOUT.toString());
|
args.push('TIMEOUT', options.TIMEOUT.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.STEPS) {
|
||||||
|
for (const step of options.STEPS) {
|
||||||
|
args.push(step.type);
|
||||||
|
switch (step.type) {
|
||||||
|
case FT_AGGREGATE_STEPS.GROUPBY:
|
||||||
|
if (!step.properties) {
|
||||||
|
args.push('0');
|
||||||
|
} else {
|
||||||
|
pushVariadicArgument(args, step.properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(step.REDUCE)) {
|
||||||
|
for (const reducer of step.REDUCE) {
|
||||||
|
pushGroupByReducer(args, reducer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pushGroupByReducer(args, step.REDUCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_STEPS.SORTBY:
|
||||||
|
const length = args.push('');
|
||||||
|
|
||||||
|
if (Array.isArray(step.BY)) {
|
||||||
|
for (const by of step.BY) {
|
||||||
|
pushSortByProperty(args, by);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pushSortByProperty(args, step.BY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step.MAX) {
|
||||||
|
args.push('MAX', step.MAX.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
args[length - 1] = (args.length - length).toString();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_STEPS.APPLY:
|
||||||
|
args.push('APPLY', step.expression, 'AS', step.AS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_STEPS.LIMIT:
|
||||||
|
args.push('LIMIT', step.from.toString(), step.size.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_STEPS.FILTER:
|
||||||
|
args.push('FILTER', step.expression);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pushParamsArgument(args, options?.PARAMS);
|
||||||
|
|
||||||
|
if (options?.DIALECT !== undefined) {
|
||||||
|
args.push('DIALECT', options.DIALECT.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
},
|
||||||
|
transformReply: undefined as unknown as () => any
|
||||||
|
} as const satisfies Command;
|
||||||
|
|
||||||
|
function pushLoadField(args: Array<RedisArgument>, toLoad: LoadField) {
|
||||||
|
if (typeof toLoad === 'string' || toLoad instanceof Buffer) {
|
||||||
|
args.push(toLoad);
|
||||||
|
} else {
|
||||||
|
args.push(toLoad.identifier);
|
||||||
|
|
||||||
|
if (toLoad.AS) {
|
||||||
|
args.push('AS', toLoad.AS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushLoadField(args: RedisCommandArguments, toLoad: LoadField): void {
|
function pushGroupByReducer(args: Array<RedisArgument>, reducer: GroupByReducers) {
|
||||||
if (typeof toLoad === 'string') {
|
args.push('REDUCE', reducer.type);
|
||||||
args.push(toLoad);
|
|
||||||
} else {
|
|
||||||
args.push(toLoad.identifier);
|
|
||||||
|
|
||||||
if (toLoad.AS) {
|
switch (reducer.type) {
|
||||||
args.push('AS', toLoad.AS);
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT:
|
||||||
|
args.push('0');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT_DISTINCT:
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT_DISTINCTISH:
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.SUM:
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.MIN:
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.MAX:
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.QUANTILE:
|
||||||
|
args.push('2', reducer.property, reducer.quantile.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.FIRST_VALUE: {
|
||||||
|
const length = args.push('', reducer.property) - 1;
|
||||||
|
if (reducer.BY) {
|
||||||
|
args.push('BY');
|
||||||
|
if (typeof reducer.BY === 'string' || reducer.BY instanceof Buffer) {
|
||||||
|
args.push(reducer.BY);
|
||||||
|
} else {
|
||||||
|
args.push(reducer.BY.property);
|
||||||
|
if (reducer.BY.direction) {
|
||||||
|
args.push(reducer.BY.direction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args[length - 1] = (args.length - length).toString();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FT_AGGREGATE_GROUP_BY_REDUCERS.RANDOM_SAMPLE:
|
||||||
|
args.push('2', reducer.property, reducer.sampleSize.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reducer.AS) {
|
||||||
|
args.push('AS', reducer.AS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushGroupByReducer(args: RedisCommandArguments, reducer: GroupByReducers): void {
|
function pushSortByProperty(args: Array<RedisArgument>, sortBy: SortByProperty) {
|
||||||
args.push('REDUCE', reducer.type);
|
if (typeof sortBy === 'string' || sortBy instanceof Buffer) {
|
||||||
|
args.push(sortBy);
|
||||||
switch (reducer.type) {
|
} else {
|
||||||
case AggregateGroupByReducers.COUNT:
|
args.push(sortBy.BY);
|
||||||
args.push('0');
|
if (sortBy.DIRECTION) {
|
||||||
break;
|
args.push(sortBy.DIRECTION);
|
||||||
|
|
||||||
case AggregateGroupByReducers.COUNT_DISTINCT:
|
|
||||||
case AggregateGroupByReducers.COUNT_DISTINCTISH:
|
|
||||||
case AggregateGroupByReducers.SUM:
|
|
||||||
case AggregateGroupByReducers.MIN:
|
|
||||||
case AggregateGroupByReducers.MAX:
|
|
||||||
case AggregateGroupByReducers.AVG:
|
|
||||||
case AggregateGroupByReducers.STDDEV:
|
|
||||||
case AggregateGroupByReducers.TOLIST:
|
|
||||||
args.push('1', reducer.property);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateGroupByReducers.QUANTILE:
|
|
||||||
args.push('2', reducer.property, reducer.quantile.toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AggregateGroupByReducers.FIRST_VALUE: {
|
|
||||||
pushArgumentsWithLength(args, () => {
|
|
||||||
args.push(reducer.property);
|
|
||||||
|
|
||||||
if (reducer.BY) {
|
|
||||||
args.push('BY');
|
|
||||||
if (typeof reducer.BY === 'string') {
|
|
||||||
args.push(reducer.BY);
|
|
||||||
} else {
|
|
||||||
args.push(reducer.BY.property);
|
|
||||||
|
|
||||||
if (reducer.BY.direction) {
|
|
||||||
args.push(reducer.BY.direction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case AggregateGroupByReducers.RANDOM_SAMPLE:
|
|
||||||
args.push('2', reducer.property, reducer.sampleSize.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reducer.AS) {
|
|
||||||
args.push('AS', reducer.AS);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AggregateRawReply = [
|
|
||||||
total: number,
|
|
||||||
...results: Array<Array<RedisCommandArgument>>
|
|
||||||
];
|
|
||||||
|
|
||||||
export interface AggregateReply {
|
|
||||||
total: number;
|
|
||||||
results: Array<Record<string, RedisCommandArgument>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply(rawReply: AggregateRawReply): AggregateReply {
|
|
||||||
const results: Array<Record<string, RedisCommandArgument>> = [];
|
|
||||||
for (let i = 1; i < rawReply.length; i++) {
|
|
||||||
results.push(
|
|
||||||
transformTuplesReply(rawReply[i] as Array<RedisCommandArgument>)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
total: rawReply[0],
|
|
||||||
results
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,37 +1,47 @@
|
|||||||
import { strict as assert } from 'node:assert';
|
import { strict as assert } from 'node:assert';
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments } from './AGGREGATE_WITHCURSOR';
|
import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR';
|
||||||
import { SchemaFieldTypes } from '.';
|
|
||||||
|
|
||||||
describe('AGGREGATE WITHCURSOR', () => {
|
describe('AGGREGATE WITHCURSOR', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without options', () => {
|
it('without options', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', '*'),
|
AGGREGATE_WITHCURSOR.transformArguments('index', '*'),
|
||||||
['FT.AGGREGATE', 'index', '*', 'WITHCURSOR']
|
['FT.AGGREGATE', 'index', '*', 'WITHCURSOR']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with COUNT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', '*', { COUNT: 1 }),
|
|
||||||
['FT.AGGREGATE', 'index', '*', 'WITHCURSOR', 'COUNT', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.ft.aggregateWithCursor', async client => {
|
it('with COUNT', () => {
|
||||||
await client.ft.create('index', {
|
assert.deepEqual(
|
||||||
field: SchemaFieldTypes.NUMERIC
|
AGGREGATE_WITHCURSOR.transformArguments('index', '*', {
|
||||||
});
|
COUNT: 1
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'WITHCURSOR', 'COUNT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
assert.deepEqual(
|
it('with MAXIDLE', () => {
|
||||||
await client.ft.aggregateWithCursor('index', '*'),
|
assert.deepEqual(
|
||||||
{
|
AGGREGATE_WITHCURSOR.transformArguments('index', '*', {
|
||||||
total: 0,
|
MAXIDLE: 1
|
||||||
results: [],
|
}),
|
||||||
cursor: 0
|
['FT.AGGREGATE', 'index', '*', 'WITHCURSOR', 'MAXIDLE', '1']
|
||||||
}
|
);
|
||||||
);
|
});
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.ft.aggregateWithCursor', async client => {
|
||||||
|
await client.ft.create('index', {
|
||||||
|
field: 'NUMERIC'
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.ft.aggregateWithCursor('index', '*'),
|
||||||
|
{
|
||||||
|
total: 0,
|
||||||
|
results: [],
|
||||||
|
cursor: 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,44 +1,73 @@
|
|||||||
import {
|
// import {
|
||||||
AggregateOptions,
|
// AggregateOptions,
|
||||||
AggregateRawReply,
|
// AggregateRawReply,
|
||||||
AggregateReply,
|
// AggregateReply,
|
||||||
transformArguments as transformAggregateArguments,
|
// transformArguments as transformAggregateArguments,
|
||||||
transformReply as transformAggregateReply
|
// transformReply as transformAggregateReply
|
||||||
} from './AGGREGATE';
|
// } from './AGGREGATE';
|
||||||
|
|
||||||
export { FIRST_KEY_INDEX, IS_READ_ONLY } from './AGGREGATE';
|
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './AGGREGATE';
|
||||||
|
|
||||||
interface AggregateWithCursorOptions extends AggregateOptions {
|
// interface AggregateWithCursorOptions extends AggregateOptions {
|
||||||
COUNT?: number;
|
// COUNT?: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function transformArguments(
|
||||||
|
// index: string,
|
||||||
|
// query: string,
|
||||||
|
// options?: AggregateWithCursorOptions
|
||||||
|
// ) {
|
||||||
|
// const args = transformAggregateArguments(index, query, options);
|
||||||
|
|
||||||
|
// args.push('WITHCURSOR');
|
||||||
|
// if (options?.COUNT) {
|
||||||
|
// args.push('COUNT', options.COUNT.toString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return args;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type AggregateWithCursorRawReply = [
|
||||||
|
// result: AggregateRawReply,
|
||||||
|
// cursor: number
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// interface AggregateWithCursorReply extends AggregateReply {
|
||||||
|
// cursor: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function transformReply(reply: AggregateWithCursorRawReply): AggregateWithCursorReply {
|
||||||
|
// return {
|
||||||
|
// ...transformAggregateReply(reply[0]),
|
||||||
|
// cursor: reply[1]
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import AGGREGATE, { FtAggregateOptions } from './AGGREGATE';
|
||||||
|
|
||||||
|
export interface FtAggregateWithCursorOptions extends FtAggregateOptions {
|
||||||
|
COUNT?: number;
|
||||||
|
MAXIDLE?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
index: string,
|
FIRST_KEY_INDEX: AGGREGATE.FIRST_KEY_INDEX,
|
||||||
query: string,
|
IS_READ_ONLY: AGGREGATE.IS_READ_ONLY,
|
||||||
options?: AggregateWithCursorOptions
|
transformArguments(index: RedisArgument, query: RedisArgument, options?: FtAggregateWithCursorOptions) {
|
||||||
) {
|
const args = AGGREGATE.transformArguments(index, query, options);
|
||||||
const args = transformAggregateArguments(index, query, options);
|
|
||||||
|
|
||||||
args.push('WITHCURSOR');
|
args.push('WITHCURSOR');
|
||||||
if (options?.COUNT) {
|
|
||||||
args.push('COUNT', options.COUNT.toString());
|
if (options?.COUNT !== undefined) {
|
||||||
|
args.push('COUNT', options.COUNT.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options?.MAXIDLE !== undefined) {
|
||||||
|
args.push('MAXIDLE', options.MAXIDLE.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => any
|
||||||
|
} as const satisfies Command;
|
||||||
|
|
||||||
type AggregateWithCursorRawReply = [
|
|
||||||
result: AggregateRawReply,
|
|
||||||
cursor: number
|
|
||||||
];
|
|
||||||
|
|
||||||
interface AggregateWithCursorReply extends AggregateReply {
|
|
||||||
cursor: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply(reply: AggregateWithCursorRawReply): AggregateWithCursorReply {
|
|
||||||
return {
|
|
||||||
...transformAggregateReply(reply[0]),
|
|
||||||
cursor: reply[1]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { RedisArgument, SimpleStringReply, Command, CommandArguments } from '@redis/client/dist/lib/RESP/types';
|
import { RedisArgument, SimpleStringReply, Command, CommandArguments } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { RedisVariadicArgument, pushOptionalVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisVariadicArgument, pushOptionalVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
import { PropertyName } from '.';
|
|
||||||
|
|
||||||
export const SCHEMA_FIELD_TYPE = {
|
export const SCHEMA_FIELD_TYPE = {
|
||||||
TEXT: 'TEXT',
|
TEXT: 'TEXT',
|
||||||
@@ -257,14 +256,16 @@ export const REDISEARCH_LANGUAGE = {
|
|||||||
|
|
||||||
export type RediSearchLanguage = typeof REDISEARCH_LANGUAGE[keyof typeof REDISEARCH_LANGUAGE];
|
export type RediSearchLanguage = typeof REDISEARCH_LANGUAGE[keyof typeof REDISEARCH_LANGUAGE];
|
||||||
|
|
||||||
|
export type RediSearchProperty = `${'@' | '$.'}${string}`;
|
||||||
|
|
||||||
export interface CreateOptions {
|
export interface CreateOptions {
|
||||||
ON?: 'HASH' | 'JSON';
|
ON?: 'HASH' | 'JSON';
|
||||||
PREFIX?: RedisVariadicArgument;
|
PREFIX?: RedisVariadicArgument;
|
||||||
FILTER?: RedisArgument;
|
FILTER?: RedisArgument;
|
||||||
LANGUAGE?: RediSearchLanguage;
|
LANGUAGE?: RediSearchLanguage;
|
||||||
LANGUAGE_FIELD?: PropertyName;
|
LANGUAGE_FIELD?: RediSearchProperty;
|
||||||
SCORE?: number;
|
SCORE?: number;
|
||||||
SCORE_FIELD?: PropertyName;
|
SCORE_FIELD?: RediSearchProperty;
|
||||||
// PAYLOAD_FIELD?: string;
|
// PAYLOAD_FIELD?: string;
|
||||||
MAXTEXTFIELDS?: boolean;
|
MAXTEXTFIELDS?: boolean;
|
||||||
TEMPORARY?: number;
|
TEMPORARY?: number;
|
||||||
|
@@ -1,300 +1,327 @@
|
|||||||
import { strict as assert } from 'node:assert';
|
import { strict as assert } from 'node:assert';
|
||||||
import { RedisSearchLanguages, SchemaFieldTypes } from '.';
|
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments } from './SEARCH';
|
import SEARCH from './SEARCH';
|
||||||
|
|
||||||
describe('SEARCH', () => {
|
describe('FT.SEARCH', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without options', () => {
|
it('without options', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', 'query'),
|
SEARCH.transformArguments('index', 'query'),
|
||||||
['FT.SEARCH', 'index', 'query']
|
['FT.SEARCH', 'index', 'query']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with VERBATIM', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { VERBATIM: true }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'VERBATIM']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with NOSTOPWORDS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { NOSTOPWORDS: true }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'NOSTOPWORDS']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with INKEYS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { INKEYS: 'key' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'INKEYS', '1', 'key']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with INFIELDS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { INFIELDS: 'field' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'INFIELDS', '1', 'field']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with RETURN', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { RETURN: 'return' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'RETURN', '1', 'return']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with SUMMARIZE', () => {
|
|
||||||
it('true', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { SUMMARIZE: true }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with FIELDS', () => {
|
|
||||||
it('string', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
SUMMARIZE: {
|
|
||||||
FIELDS: ['@field']
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '1', '@field']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Array', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
SUMMARIZE: {
|
|
||||||
FIELDS: ['@1', '@2']
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '2', '@1', '@2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with FRAGS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
SUMMARIZE: {
|
|
||||||
FRAGS: 1
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FRAGS', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with LEN', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
SUMMARIZE: {
|
|
||||||
LEN: 1
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'LEN', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with SEPARATOR', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
SUMMARIZE: {
|
|
||||||
SEPARATOR: 'separator'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'SEPARATOR', 'separator']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with HIGHLIGHT', () => {
|
|
||||||
it('true', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { HIGHLIGHT: true }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with FIELDS', () => {
|
|
||||||
it('string', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
HIGHLIGHT: {
|
|
||||||
FIELDS: ['@field']
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '1', '@field']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Array', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
HIGHLIGHT: {
|
|
||||||
FIELDS: ['@1', '@2']
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '2', '@1', '@2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with TAGS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
HIGHLIGHT: {
|
|
||||||
TAGS: {
|
|
||||||
open: 'open',
|
|
||||||
close: 'close'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'TAGS', 'open', 'close']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with SLOP', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { SLOP: 1 }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SLOP', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with INORDER', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { INORDER: true }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'INORDER']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with LANGUAGE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { LANGUAGE: RedisSearchLanguages.ARABIC }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'LANGUAGE', RedisSearchLanguages.ARABIC]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with EXPANDER', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { EXPANDER: 'expender' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'EXPANDER', 'expender']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with SCORER', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { SCORER: 'scorer' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SCORER', 'scorer']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with SORTBY', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', { SORTBY: '@by' }),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'SORTBY', '@by']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with LIMIT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
LIMIT: {
|
|
||||||
from: 0,
|
|
||||||
size: 1
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'LIMIT', '0', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with PARAMS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
PARAMS: {
|
|
||||||
param: 'value'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'PARAMS', '2', 'param', 'value']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with DIALECT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
DIALECT: 1
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'DIALECT', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with TIMEOUT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('index', 'query', {
|
|
||||||
TIMEOUT: 5
|
|
||||||
}),
|
|
||||||
['FT.SEARCH', 'index', 'query', 'TIMEOUT', '5']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('client.ft.search', () => {
|
it('with VERBATIM', () => {
|
||||||
testUtils.testWithClient('without optional options', async client => {
|
assert.deepEqual(
|
||||||
await Promise.all([
|
SEARCH.transformArguments('index', 'query', {
|
||||||
client.ft.create('index', {
|
VERBATIM: true
|
||||||
field: SchemaFieldTypes.NUMERIC
|
}),
|
||||||
}),
|
['FT.SEARCH', 'index', 'query', 'VERBATIM']
|
||||||
client.hSet('1', 'field', '1')
|
);
|
||||||
]);
|
|
||||||
|
|
||||||
assert.deepEqual(
|
|
||||||
await client.ft.search('index', '*'),
|
|
||||||
{
|
|
||||||
total: 1,
|
|
||||||
documents: [{
|
|
||||||
id: '1',
|
|
||||||
value: Object.create(null, {
|
|
||||||
field: {
|
|
||||||
value: '1',
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
|
|
||||||
testUtils.testWithClient('RETURN []', async client => {
|
|
||||||
await Promise.all([
|
|
||||||
client.ft.create('index', {
|
|
||||||
field: SchemaFieldTypes.NUMERIC
|
|
||||||
}),
|
|
||||||
client.hSet('1', 'field', '1'),
|
|
||||||
client.hSet('2', 'field', '2')
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.deepEqual(
|
|
||||||
await client.ft.search('index', '*', {
|
|
||||||
RETURN: []
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
total: 2,
|
|
||||||
documents: [{
|
|
||||||
id: '1',
|
|
||||||
value: Object.create(null)
|
|
||||||
}, {
|
|
||||||
id: '2',
|
|
||||||
value: Object.create(null)
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with NOSTOPWORDS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
NOSTOPWORDS: true
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'NOSTOPWORDS']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with INKEYS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
INKEYS: 'key'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'INKEYS', '1', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with INFIELDS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
INFIELDS: 'field'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'INFIELDS', '1', 'field']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with RETURN', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
RETURN: 'return'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'RETURN', '1', 'return']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with SUMMARIZE', () => {
|
||||||
|
it('true', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: true
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with FIELDS', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: {
|
||||||
|
FIELDS: '@field'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '1', '@field']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: {
|
||||||
|
FIELDS: ['@1', '@2']
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '2', '@1', '@2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with FRAGS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: {
|
||||||
|
FRAGS: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FRAGS', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with LEN', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: {
|
||||||
|
LEN: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'LEN', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with SEPARATOR', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SUMMARIZE: {
|
||||||
|
SEPARATOR: 'separator'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'SEPARATOR', 'separator']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with HIGHLIGHT', () => {
|
||||||
|
it('true', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
HIGHLIGHT: true
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with FIELDS', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
HIGHLIGHT: {
|
||||||
|
FIELDS: ['@field']
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '1', '@field']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
HIGHLIGHT: {
|
||||||
|
FIELDS: ['@1', '@2']
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '2', '@1', '@2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with TAGS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
HIGHLIGHT: {
|
||||||
|
TAGS: {
|
||||||
|
open: 'open',
|
||||||
|
close: 'close'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'TAGS', 'open', 'close']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with SLOP', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SLOP: 1
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SLOP', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with TIMEOUT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
TIMEOUT: 1
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'TIMEOUT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with INORDER', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
INORDER: true
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'INORDER']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with LANGUAGE', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
LANGUAGE: 'Arabic'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'LANGUAGE', 'Arabic']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with EXPANDER', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
EXPANDER: 'expender'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'EXPANDER', 'expender']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with SCORER', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SCORER: 'scorer'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SCORER', 'scorer']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with SORTBY', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
SORTBY: '@by'
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'SORTBY', '@by']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with LIMIT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
LIMIT: {
|
||||||
|
from: 0,
|
||||||
|
size: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'LIMIT', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with PARAMS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
PARAMS: {
|
||||||
|
string: 'string',
|
||||||
|
buffer: Buffer.from('buffer'),
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'PARAMS', '6', 'string', 'string', 'buffer', Buffer.from('buffer'), 'number', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with DIALECT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
SEARCH.transformArguments('index', 'query', {
|
||||||
|
DIALECT: 1
|
||||||
|
}),
|
||||||
|
['FT.SEARCH', 'index', 'query', 'DIALECT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('client.ft.search', () => {
|
||||||
|
testUtils.testWithClient('without optional options', async client => {
|
||||||
|
await Promise.all([
|
||||||
|
client.ft.create('index', {
|
||||||
|
field: 'TEXT'
|
||||||
|
}),
|
||||||
|
client.hSet('1', 'field', '1')
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.ft.search('index', '*'),
|
||||||
|
{
|
||||||
|
total: 1,
|
||||||
|
documents: [{
|
||||||
|
id: '1',
|
||||||
|
value: Object.create(null, {
|
||||||
|
field: {
|
||||||
|
value: '1',
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
|
||||||
|
testUtils.testWithClient('RETURN []', async client => {
|
||||||
|
await Promise.all([
|
||||||
|
client.ft.create('index', {
|
||||||
|
field: 'TEXT'
|
||||||
|
}),
|
||||||
|
client.hSet('1', 'field', '1'),
|
||||||
|
client.hSet('2', 'field', '2')
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.ft.search('index', '*', {
|
||||||
|
RETURN: []
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
total: 2,
|
||||||
|
documents: [{
|
||||||
|
id: '1',
|
||||||
|
value: Object.create(null)
|
||||||
|
}, {
|
||||||
|
id: '2',
|
||||||
|
value: Object.create(null)
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,109 +1,162 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushSearchOptions, RedisSearchLanguages, Params, PropertyName, SortByProperty, SearchReply } from '.';
|
import { RedisVariadicArgument, pushOptionalVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
import { RediSearchProperty, RediSearchLanguage } from './CREATE';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export type FtSearchParams = Record<string, RedisArgument | number>;
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export function pushParamsArgument(args: Array<RedisArgument>, params?: FtSearchParams) {
|
||||||
|
if (params) {
|
||||||
|
const length = args.push('PARAMS', '');
|
||||||
|
for (const key in params) {
|
||||||
|
if (!Object.hasOwn(params, key)) continue;
|
||||||
|
|
||||||
export interface SearchOptions {
|
const value = params[key];
|
||||||
VERBATIM?: true;
|
args.push(
|
||||||
NOSTOPWORDS?: true;
|
key,
|
||||||
// WITHSCORES?: true;
|
typeof value === 'number' ? value.toString() : value
|
||||||
// WITHPAYLOADS?: true;
|
);
|
||||||
WITHSORTKEYS?: true;
|
|
||||||
// FILTER?: {
|
|
||||||
// field: string;
|
|
||||||
// min: number | string;
|
|
||||||
// max: number | string;
|
|
||||||
// };
|
|
||||||
// GEOFILTER?: {
|
|
||||||
// field: string;
|
|
||||||
// lon: number;
|
|
||||||
// lat: number;
|
|
||||||
// radius: number;
|
|
||||||
// unit: 'm' | 'km' | 'mi' | 'ft';
|
|
||||||
// };
|
|
||||||
INKEYS?: string | Array<string>;
|
|
||||||
INFIELDS?: string | Array<string>;
|
|
||||||
RETURN?: string | Array<string>;
|
|
||||||
SUMMARIZE?: true | {
|
|
||||||
FIELDS?: PropertyName | Array<PropertyName>;
|
|
||||||
FRAGS?: number;
|
|
||||||
LEN?: number;
|
|
||||||
SEPARATOR?: string;
|
|
||||||
};
|
|
||||||
HIGHLIGHT?: true | {
|
|
||||||
FIELDS?: PropertyName | Array<PropertyName>;
|
|
||||||
TAGS?: {
|
|
||||||
open: string;
|
|
||||||
close: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
SLOP?: number;
|
|
||||||
INORDER?: true;
|
|
||||||
LANGUAGE?: RedisSearchLanguages;
|
|
||||||
EXPANDER?: string;
|
|
||||||
SCORER?: string;
|
|
||||||
// EXPLAINSCORE?: true; // TODO: WITHSCORES
|
|
||||||
// PAYLOAD?: ;
|
|
||||||
SORTBY?: SortByProperty;
|
|
||||||
// MSORTBY?: SortByProperty | Array<SortByProperty>;
|
|
||||||
LIMIT?: {
|
|
||||||
from: number | string;
|
|
||||||
size: number | string;
|
|
||||||
};
|
|
||||||
PARAMS?: Params;
|
|
||||||
DIALECT?: number;
|
|
||||||
TIMEOUT?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformArguments(
|
|
||||||
index: string,
|
|
||||||
query: string,
|
|
||||||
options?: SearchOptions
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushSearchOptions(
|
|
||||||
['FT.SEARCH', index, query],
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SearchRawReply = Array<any>;
|
|
||||||
|
|
||||||
export function transformReply(reply: SearchRawReply, withoutDocuments: boolean): SearchReply {
|
|
||||||
const documents = [];
|
|
||||||
let i = 1;
|
|
||||||
while (i < reply.length) {
|
|
||||||
documents.push({
|
|
||||||
id: reply[i++],
|
|
||||||
value: withoutDocuments ? Object.create(null) : documentValue(reply[i++])
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
args[length - 1] = (args.length - length).toString();
|
||||||
total: reply[0],
|
}
|
||||||
documents
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function documentValue(tuples: any) {
|
export interface FtSearchOptions {
|
||||||
const message = Object.create(null);
|
VERBATIM?: boolean;
|
||||||
|
NOSTOPWORDS?: boolean;
|
||||||
|
INKEYS?: RedisVariadicArgument;
|
||||||
|
INFIELDS?: RedisVariadicArgument;
|
||||||
|
RETURN?: RedisVariadicArgument;
|
||||||
|
SUMMARIZE?: boolean | {
|
||||||
|
FIELDS?: RediSearchProperty | Array<RediSearchProperty>;
|
||||||
|
FRAGS?: number;
|
||||||
|
LEN?: number;
|
||||||
|
SEPARATOR?: RedisArgument;
|
||||||
|
};
|
||||||
|
HIGHLIGHT?: boolean | {
|
||||||
|
FIELDS?: RediSearchProperty | Array<RediSearchProperty>;
|
||||||
|
TAGS?: {
|
||||||
|
open: RedisArgument;
|
||||||
|
close: RedisArgument;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
SLOP?: number;
|
||||||
|
TIMEOUT?: number;
|
||||||
|
INORDER?: boolean;
|
||||||
|
LANGUAGE?: RediSearchLanguage;
|
||||||
|
EXPANDER?: RedisArgument;
|
||||||
|
SCORER?: RedisArgument;
|
||||||
|
SORTBY?: RedisArgument | {
|
||||||
|
BY: RediSearchProperty;
|
||||||
|
DIRECTION?: 'ASC' | 'DESC';
|
||||||
|
};
|
||||||
|
LIMIT?: {
|
||||||
|
from: number | RedisArgument;
|
||||||
|
size: number | RedisArgument;
|
||||||
|
};
|
||||||
|
PARAMS?: FtSearchParams;
|
||||||
|
DIALECT?: number;
|
||||||
|
}
|
||||||
|
|
||||||
let i = 0;
|
export default {
|
||||||
while (i < tuples.length) {
|
FIRST_KEY_INDEX: undefined,
|
||||||
const key = tuples[i++],
|
IS_READ_ONLY: true,
|
||||||
value = tuples[i++];
|
transformArguments(index: RedisArgument, query: RedisArgument, options?: FtSearchOptions) {
|
||||||
if (key === '$') { // might be a JSON reply
|
const args = ['FT.SEARCH', index, query];
|
||||||
try {
|
|
||||||
Object.assign(message, JSON.parse(value));
|
if (options?.VERBATIM) {
|
||||||
continue;
|
args.push('VERBATIM');
|
||||||
} catch {
|
}
|
||||||
// set as a regular property if not a valid JSON
|
|
||||||
}
|
if (options?.NOSTOPWORDS) {
|
||||||
|
args.push('NOSTOPWORDS');
|
||||||
|
}
|
||||||
|
|
||||||
|
pushOptionalVariadicArgument(args, 'INKEYS', options?.INKEYS);
|
||||||
|
pushOptionalVariadicArgument(args, 'INFIELDS', options?.INFIELDS);
|
||||||
|
pushOptionalVariadicArgument(args, 'RETURN', options?.RETURN);
|
||||||
|
|
||||||
|
if (options?.SUMMARIZE) {
|
||||||
|
args.push('SUMMARIZE');
|
||||||
|
|
||||||
|
if (typeof options.SUMMARIZE === 'object') {
|
||||||
|
pushOptionalVariadicArgument(args, 'FIELDS', options.SUMMARIZE.FIELDS);
|
||||||
|
|
||||||
|
if (options.SUMMARIZE.FRAGS !== undefined) {
|
||||||
|
args.push('FRAGS', options.SUMMARIZE.FRAGS.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
message[key] = value;
|
if (options.SUMMARIZE.LEN !== undefined) {
|
||||||
|
args.push('LEN', options.SUMMARIZE.LEN.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.SUMMARIZE.SEPARATOR !== undefined) {
|
||||||
|
args.push('SEPARATOR', options.SUMMARIZE.SEPARATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
if (options?.HIGHLIGHT) {
|
||||||
}
|
args.push('HIGHLIGHT');
|
||||||
|
|
||||||
|
if (typeof options.HIGHLIGHT === 'object') {
|
||||||
|
pushOptionalVariadicArgument(args, 'FIELDS', options.HIGHLIGHT.FIELDS);
|
||||||
|
|
||||||
|
if (options.HIGHLIGHT.TAGS) {
|
||||||
|
args.push('TAGS', options.HIGHLIGHT.TAGS.open, options.HIGHLIGHT.TAGS.close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.SLOP !== undefined) {
|
||||||
|
args.push('SLOP', options.SLOP.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.TIMEOUT !== undefined) {
|
||||||
|
args.push('TIMEOUT', options.TIMEOUT.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.INORDER) {
|
||||||
|
args.push('INORDER');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.LANGUAGE) {
|
||||||
|
args.push('LANGUAGE', options.LANGUAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.EXPANDER) {
|
||||||
|
args.push('EXPANDER', options.EXPANDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.SCORER) {
|
||||||
|
args.push('SCORER', options.SCORER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.SORTBY) {
|
||||||
|
args.push('SORTBY');
|
||||||
|
|
||||||
|
if (typeof options.SORTBY === 'string' || options.SORTBY instanceof Buffer) {
|
||||||
|
args.push(options.SORTBY);
|
||||||
|
} else {
|
||||||
|
args.push(options.SORTBY.BY);
|
||||||
|
|
||||||
|
if (options.SORTBY.DIRECTION) {
|
||||||
|
args.push(options.SORTBY.DIRECTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.LIMIT) {
|
||||||
|
args.push('LIMIT', options.LIMIT.from.toString(), options.LIMIT.size.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
pushParamsArgument(args, options?.PARAMS);
|
||||||
|
|
||||||
|
if (options?.DIALECT !== undefined) {
|
||||||
|
args.push('DIALECT', options.DIALECT.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
},
|
||||||
|
transformReply: undefined as unknown as () => any
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,45 +1,34 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import { SchemaFieldTypes } from '.';
|
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments, transformReply } from './SEARCH_NOCONTENT';
|
import SEARCH_NOCONTENT from './SEARCH_NOCONTENT';
|
||||||
|
|
||||||
describe('SEARCH_NOCONTENT', () => {
|
describe('FT.SEARCH NOCONTENT', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without options', () => {
|
it('without options', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('index', 'query'),
|
SEARCH_NOCONTENT.transformArguments('index', 'query'),
|
||||||
['FT.SEARCH', 'index', 'query', 'NOCONTENT']
|
['FT.SEARCH', 'index', 'query', 'NOCONTENT']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('transformReply', () => {
|
describe('client.ft.searchNoContent', () => {
|
||||||
it('returns total and keys', () => {
|
testUtils.testWithClient('returns total and keys', async client => {
|
||||||
assert.deepEqual(transformReply([3, '1', '2', '3']), {
|
await Promise.all([
|
||||||
total: 3,
|
client.ft.create('index', {
|
||||||
documents: ['1', '2', '3']
|
field: 'TEXT'
|
||||||
})
|
}),
|
||||||
});
|
client.hSet('1', 'field', 'field1'),
|
||||||
});
|
client.hSet('2', 'field', 'field2')
|
||||||
|
]);
|
||||||
|
|
||||||
describe('client.ft.searchNoContent', () => {
|
assert.deepEqual(
|
||||||
testUtils.testWithClient('returns total and keys', async client => {
|
await client.ft.searchNoContent('index', '*'),
|
||||||
await Promise.all([
|
{
|
||||||
client.ft.create('index', {
|
total: 2,
|
||||||
field: SchemaFieldTypes.TEXT
|
documents: ['1', '2']
|
||||||
}),
|
}
|
||||||
client.hSet('1', 'field', 'field1'),
|
);
|
||||||
client.hSet('2', 'field', 'field2'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
client.hSet('3', 'field', 'field3')
|
});
|
||||||
]);
|
|
||||||
|
|
||||||
assert.deepEqual(
|
|
||||||
await client.ft.searchNoContent('index', '*'),
|
|
||||||
{
|
|
||||||
total: 3,
|
|
||||||
documents: ['1','2','3']
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -1,30 +1,13 @@
|
|||||||
import { RedisCommandArguments } from "@redis/client/dist/lib/commands";
|
import { Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushSearchOptions } from ".";
|
import SEARCH from './SEARCH';
|
||||||
import { SearchOptions, SearchRawReply } from "./SEARCH";
|
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: SEARCH.FIRST_KEY_INDEX,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: SEARCH.IS_READ_ONLY,
|
||||||
|
transformArguments(...args: Parameters<typeof SEARCH.transformArguments>) {
|
||||||
export function transformArguments(
|
const redisArgs = SEARCH.transformArguments(...args);
|
||||||
index: string,
|
redisArgs.push('NOCONTENT');
|
||||||
query: string,
|
return redisArgs;
|
||||||
options?: SearchOptions
|
},
|
||||||
): RedisCommandArguments {
|
transformReply: undefined as unknown as () => any
|
||||||
return pushSearchOptions(
|
} as const satisfies Command;
|
||||||
['FT.SEARCH', index, query, 'NOCONTENT'],
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchNoContentReply {
|
|
||||||
total: number;
|
|
||||||
documents: Array<string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function transformReply(reply: SearchRawReply): SearchNoContentReply {
|
|
||||||
return {
|
|
||||||
total: reply[0],
|
|
||||||
documents: reply.slice(1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import _LIST from './_LIST';
|
import _LIST from './_LIST';
|
||||||
import ALTER from './ALTER';
|
import ALTER from './ALTER';
|
||||||
// import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR';
|
import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR';
|
||||||
// import AGGREGATE from './AGGREGATE';
|
import AGGREGATE from './AGGREGATE';
|
||||||
import ALIASADD from './ALIASADD';
|
import ALIASADD from './ALIASADD';
|
||||||
import ALIASDEL from './ALIASDEL';
|
import ALIASDEL from './ALIASDEL';
|
||||||
import ALIASUPDATE from './ALIASUPDATE';
|
import ALIASUPDATE from './ALIASUPDATE';
|
||||||
@@ -19,7 +19,8 @@ import DROPINDEX from './DROPINDEX';
|
|||||||
// import INFO from './INFO';
|
// import INFO from './INFO';
|
||||||
// import PROFILESEARCH from './PROFILE_SEARCH';
|
// import PROFILESEARCH from './PROFILE_SEARCH';
|
||||||
// import PROFILEAGGREGATE from './PROFILE_AGGREGATE';
|
// import PROFILEAGGREGATE from './PROFILE_AGGREGATE';
|
||||||
// import SEARCH from './SEARCH';
|
import SEARCH_NOCONTENT from './SEARCH_NOCONTENT';
|
||||||
|
import SEARCH from './SEARCH';
|
||||||
import SPELLCHECK from './SPELLCHECK';
|
import SPELLCHECK from './SPELLCHECK';
|
||||||
import SUGADD from './SUGADD';
|
import SUGADD from './SUGADD';
|
||||||
import SUGDEL from './SUGDEL';
|
import SUGDEL from './SUGDEL';
|
||||||
@@ -31,6 +32,7 @@ import SUGLEN from './SUGLEN';
|
|||||||
import SYNDUMP from './SYNDUMP';
|
import SYNDUMP from './SYNDUMP';
|
||||||
import SYNUPDATE from './SYNUPDATE';
|
import SYNUPDATE from './SYNUPDATE';
|
||||||
import TAGVALS from './TAGVALS';
|
import TAGVALS from './TAGVALS';
|
||||||
|
import { RedisArgument } from '@redis/client';
|
||||||
// import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
// import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
||||||
// import { pushOptionalVariadicArgument, pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
// import { pushOptionalVariadicArgument, pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
// import { SearchOptions } from './SEARCH';
|
// import { SearchOptions } from './SEARCH';
|
||||||
@@ -41,10 +43,10 @@ export default {
|
|||||||
_list: _LIST,
|
_list: _LIST,
|
||||||
ALTER,
|
ALTER,
|
||||||
alter: ALTER,
|
alter: ALTER,
|
||||||
// AGGREGATE_WITHCURSOR,
|
AGGREGATE_WITHCURSOR,
|
||||||
// aggregateWithCursor: AGGREGATE_WITHCURSOR,
|
aggregateWithCursor: AGGREGATE_WITHCURSOR,
|
||||||
// AGGREGATE,
|
AGGREGATE,
|
||||||
// aggregate: AGGREGATE,
|
aggregate: AGGREGATE,
|
||||||
ALIASADD,
|
ALIASADD,
|
||||||
aliasAdd: ALIASADD,
|
aliasAdd: ALIASADD,
|
||||||
ALIASDEL,
|
ALIASDEL,
|
||||||
@@ -79,8 +81,10 @@ export default {
|
|||||||
// profileSearch: PROFILESEARCH,
|
// profileSearch: PROFILESEARCH,
|
||||||
// PROFILEAGGREGATE,
|
// PROFILEAGGREGATE,
|
||||||
// profileAggregate: PROFILEAGGREGATE,
|
// profileAggregate: PROFILEAGGREGATE,
|
||||||
// SEARCH,
|
SEARCH_NOCONTENT,
|
||||||
// search: SEARCH,
|
searchNoContent: SEARCH_NOCONTENT,
|
||||||
|
SEARCH,
|
||||||
|
search: SEARCH,
|
||||||
SPELLCHECK,
|
SPELLCHECK,
|
||||||
spellCheck: SPELLCHECK,
|
spellCheck: SPELLCHECK,
|
||||||
SUGADD,
|
SUGADD,
|
||||||
@@ -104,539 +108,3 @@ export default {
|
|||||||
TAGVALS,
|
TAGVALS,
|
||||||
tagVals: TAGVALS
|
tagVals: TAGVALS
|
||||||
};
|
};
|
||||||
|
|
||||||
// export enum RedisSearchLanguages {
|
|
||||||
// ARABIC = 'Arabic',
|
|
||||||
// BASQUE = 'Basque',
|
|
||||||
// CATALANA = 'Catalan',
|
|
||||||
// DANISH = 'Danish',
|
|
||||||
// DUTCH = 'Dutch',
|
|
||||||
// ENGLISH = 'English',
|
|
||||||
// FINNISH = 'Finnish',
|
|
||||||
// FRENCH = 'French',
|
|
||||||
// GERMAN = 'German',
|
|
||||||
// GREEK = 'Greek',
|
|
||||||
// HUNGARIAN = 'Hungarian',
|
|
||||||
// INDONESAIN = 'Indonesian',
|
|
||||||
// IRISH = 'Irish',
|
|
||||||
// ITALIAN = 'Italian',
|
|
||||||
// LITHUANIAN = 'Lithuanian',
|
|
||||||
// NEPALI = 'Nepali',
|
|
||||||
// NORWEIGAN = 'Norwegian',
|
|
||||||
// PORTUGUESE = 'Portuguese',
|
|
||||||
// ROMANIAN = 'Romanian',
|
|
||||||
// RUSSIAN = 'Russian',
|
|
||||||
// SPANISH = 'Spanish',
|
|
||||||
// SWEDISH = 'Swedish',
|
|
||||||
// TAMIL = 'Tamil',
|
|
||||||
// TURKISH = 'Turkish',
|
|
||||||
// CHINESE = 'Chinese'
|
|
||||||
// }
|
|
||||||
|
|
||||||
export type PropertyName = `${'@' | '$.'}${string}`;
|
|
||||||
|
|
||||||
// export type SortByProperty = string | {
|
|
||||||
// BY: string;
|
|
||||||
// DIRECTION?: 'ASC' | 'DESC';
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export function pushSortByProperty(args: RedisCommandArguments, sortBy: SortByProperty): void {
|
|
||||||
// if (typeof sortBy === 'string') {
|
|
||||||
// args.push(sortBy);
|
|
||||||
// } else {
|
|
||||||
// args.push(sortBy.BY);
|
|
||||||
|
|
||||||
// if (sortBy.DIRECTION) {
|
|
||||||
// args.push(sortBy.DIRECTION);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function pushSortByArguments(args: RedisCommandArguments, name: string, sortBy: SortByProperty | Array<SortByProperty>): RedisCommandArguments {
|
|
||||||
// const lengthBefore = args.push(
|
|
||||||
// name,
|
|
||||||
// '' // will be overwritten
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (Array.isArray(sortBy)) {
|
|
||||||
// for (const field of sortBy) {
|
|
||||||
// pushSortByProperty(args, field);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// pushSortByProperty(args, sortBy);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// args[lengthBefore - 1] = (args.length - lengthBefore).toString();
|
|
||||||
|
|
||||||
// return args;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function pushArgumentsWithLength(args: CommandArguments, fn: (args: CommandArguments) => void) {
|
|
||||||
// const lengthIndex = args.push('') - 1;
|
|
||||||
// fn(args);
|
|
||||||
// args[lengthIndex] = (args.length - lengthIndex - 1).toString();
|
|
||||||
// return args;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export enum SchemaFieldTypes {
|
|
||||||
// TEXT = 'TEXT',
|
|
||||||
// NUMERIC = 'NUMERIC',
|
|
||||||
// GEO = 'GEO',
|
|
||||||
// TAG = 'TAG',
|
|
||||||
// VECTOR = 'VECTOR'
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type CreateSchemaField<
|
|
||||||
// T extends SchemaFieldTypes,
|
|
||||||
// E = Record<PropertyKey, unknown>
|
|
||||||
// > = T | ({
|
|
||||||
// type: T;
|
|
||||||
// AS?: string;
|
|
||||||
// } & E);
|
|
||||||
|
|
||||||
// type CreateSchemaCommonField<
|
|
||||||
// T extends SchemaFieldTypes,
|
|
||||||
// E = Record<PropertyKey, unknown>
|
|
||||||
// > = CreateSchemaField<
|
|
||||||
// T,
|
|
||||||
// ({
|
|
||||||
// SORTABLE?: true | 'UNF';
|
|
||||||
// NOINDEX?: true;
|
|
||||||
// } & E)
|
|
||||||
// >;
|
|
||||||
|
|
||||||
// export enum SchemaTextFieldPhonetics {
|
|
||||||
// DM_EN = 'dm:en',
|
|
||||||
// DM_FR = 'dm:fr',
|
|
||||||
// FM_PT = 'dm:pt',
|
|
||||||
// DM_ES = 'dm:es'
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type CreateSchemaTextField = CreateSchemaCommonField<SchemaFieldTypes.TEXT, {
|
|
||||||
// NOSTEM?: true;
|
|
||||||
// WEIGHT?: number;
|
|
||||||
// PHONETIC?: SchemaTextFieldPhonetics;
|
|
||||||
// WITHSUFFIXTRIE?: boolean;
|
|
||||||
// }>;
|
|
||||||
|
|
||||||
// type CreateSchemaNumericField = CreateSchemaCommonField<SchemaFieldTypes.NUMERIC>;
|
|
||||||
|
|
||||||
// type CreateSchemaGeoField = CreateSchemaCommonField<SchemaFieldTypes.GEO>;
|
|
||||||
|
|
||||||
// type CreateSchemaTagField = CreateSchemaCommonField<SchemaFieldTypes.TAG, {
|
|
||||||
// SEPARATOR?: string;
|
|
||||||
// CASESENSITIVE?: true;
|
|
||||||
// WITHSUFFIXTRIE?: boolean;
|
|
||||||
// }>;
|
|
||||||
|
|
||||||
// export enum VectorAlgorithms {
|
|
||||||
// FLAT = 'FLAT',
|
|
||||||
// HNSW = 'HNSW'
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type CreateSchemaVectorField<
|
|
||||||
// T extends VectorAlgorithms,
|
|
||||||
// A extends Record<string, unknown>
|
|
||||||
// > = CreateSchemaField<SchemaFieldTypes.VECTOR, {
|
|
||||||
// ALGORITHM: T;
|
|
||||||
// TYPE: string;
|
|
||||||
// DIM: number;
|
|
||||||
// DISTANCE_METRIC: 'L2' | 'IP' | 'COSINE';
|
|
||||||
// INITIAL_CAP?: number;
|
|
||||||
// } & A>;
|
|
||||||
|
|
||||||
// type CreateSchemaFlatVectorField = CreateSchemaVectorField<VectorAlgorithms.FLAT, {
|
|
||||||
// BLOCK_SIZE?: number;
|
|
||||||
// }>;
|
|
||||||
|
|
||||||
// type CreateSchemaHNSWVectorField = CreateSchemaVectorField<VectorAlgorithms.HNSW, {
|
|
||||||
// M?: number;
|
|
||||||
// EF_CONSTRUCTION?: number;
|
|
||||||
// EF_RUNTIME?: number;
|
|
||||||
// }>;
|
|
||||||
|
|
||||||
// export interface RediSearchSchema {
|
|
||||||
// [field: string]:
|
|
||||||
// CreateSchemaTextField |
|
|
||||||
// CreateSchemaNumericField |
|
|
||||||
// CreateSchemaGeoField |
|
|
||||||
// CreateSchemaTagField |
|
|
||||||
// CreateSchemaFlatVectorField |
|
|
||||||
// CreateSchemaHNSWVectorField;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema) {
|
|
||||||
// for (const [field, fieldOptions] of Object.entries(schema)) {
|
|
||||||
// args.push(field);
|
|
||||||
|
|
||||||
// if (typeof fieldOptions === 'string') {
|
|
||||||
// args.push(fieldOptions);
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.AS) {
|
|
||||||
// args.push('AS', fieldOptions.AS);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// args.push(fieldOptions.type);
|
|
||||||
|
|
||||||
// switch (fieldOptions.type) {
|
|
||||||
// case SchemaFieldTypes.TEXT:
|
|
||||||
// if (fieldOptions.NOSTEM) {
|
|
||||||
// args.push('NOSTEM');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.WEIGHT) {
|
|
||||||
// args.push('WEIGHT', fieldOptions.WEIGHT.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.PHONETIC) {
|
|
||||||
// args.push('PHONETIC', fieldOptions.PHONETIC);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.WITHSUFFIXTRIE) {
|
|
||||||
// args.push('WITHSUFFIXTRIE');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // case SchemaFieldTypes.NUMERIC:
|
|
||||||
// // case SchemaFieldTypes.GEO:
|
|
||||||
// // break;
|
|
||||||
|
|
||||||
// case SchemaFieldTypes.TAG:
|
|
||||||
// if (fieldOptions.SEPARATOR) {
|
|
||||||
// args.push('SEPARATOR', fieldOptions.SEPARATOR);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.CASESENSITIVE) {
|
|
||||||
// args.push('CASESENSITIVE');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.WITHSUFFIXTRIE) {
|
|
||||||
// args.push('WITHSUFFIXTRIE');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case SchemaFieldTypes.VECTOR:
|
|
||||||
// args.push(fieldOptions.ALGORITHM);
|
|
||||||
|
|
||||||
// pushArgumentsWithLength(args, () => {
|
|
||||||
// args.push(
|
|
||||||
// 'TYPE', fieldOptions.TYPE,
|
|
||||||
// 'DIM', fieldOptions.DIM.toString(),
|
|
||||||
// 'DISTANCE_METRIC', fieldOptions.DISTANCE_METRIC
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (fieldOptions.INITIAL_CAP) {
|
|
||||||
// args.push('INITIAL_CAP', fieldOptions.INITIAL_CAP.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// switch (fieldOptions.ALGORITHM) {
|
|
||||||
// case VectorAlgorithms.FLAT:
|
|
||||||
// if (fieldOptions.BLOCK_SIZE) {
|
|
||||||
// args.push('BLOCK_SIZE', fieldOptions.BLOCK_SIZE.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case VectorAlgorithms.HNSW:
|
|
||||||
// if (fieldOptions.M) {
|
|
||||||
// args.push('M', fieldOptions.M.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.EF_CONSTRUCTION) {
|
|
||||||
// args.push('EF_CONSTRUCTION', fieldOptions.EF_CONSTRUCTION.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.EF_RUNTIME) {
|
|
||||||
// args.push('EF_RUNTIME', fieldOptions.EF_RUNTIME.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// continue; // vector fields do not contain SORTABLE and NOINDEX options
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.SORTABLE) {
|
|
||||||
// args.push('SORTABLE');
|
|
||||||
|
|
||||||
// if (fieldOptions.SORTABLE === 'UNF') {
|
|
||||||
// args.push('UNF');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (fieldOptions.NOINDEX) {
|
|
||||||
// args.push('NOINDEX');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export type Params = Record<string, RedisCommandArgument | number>;
|
|
||||||
|
|
||||||
// export function pushParamsArgs(
|
|
||||||
// args: RedisCommandArguments,
|
|
||||||
// params?: Params
|
|
||||||
// ): RedisCommandArguments {
|
|
||||||
// if (params) {
|
|
||||||
// const enrties = Object.entries(params);
|
|
||||||
// args.push('PARAMS', (enrties.length * 2).toString());
|
|
||||||
// for (const [key, value] of enrties) {
|
|
||||||
// args.push(key, typeof value === 'number' ? value.toString() : value);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return args;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function pushSearchOptions(
|
|
||||||
// args: RedisCommandArguments,
|
|
||||||
// options?: SearchOptions
|
|
||||||
// ): RedisCommandArguments {
|
|
||||||
// if (options?.VERBATIM) {
|
|
||||||
// args.push('VERBATIM');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.NOSTOPWORDS) {
|
|
||||||
// args.push('NOSTOPWORDS');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if (options?.WITHSCORES) {
|
|
||||||
// // args.push('WITHSCORES');
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // if (options?.WITHPAYLOADS) {
|
|
||||||
// // args.push('WITHPAYLOADS');
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// pushOptionalVariadicArgument(args, 'INKEYS', options?.INKEYS);
|
|
||||||
// pushOptionalVariadicArgument(args, 'INFIELDS', options?.INFIELDS);
|
|
||||||
// pushOptionalVariadicArgument(args, 'RETURN', options?.RETURN);
|
|
||||||
|
|
||||||
// if (options?.SUMMARIZE) {
|
|
||||||
// args.push('SUMMARIZE');
|
|
||||||
|
|
||||||
// if (typeof options.SUMMARIZE === 'object') {
|
|
||||||
// if (options.SUMMARIZE.FIELDS) {
|
|
||||||
// args.push('FIELDS');
|
|
||||||
// pushVariadicArgument(args, options.SUMMARIZE.FIELDS);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options.SUMMARIZE.FRAGS) {
|
|
||||||
// args.push('FRAGS', options.SUMMARIZE.FRAGS.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options.SUMMARIZE.LEN) {
|
|
||||||
// args.push('LEN', options.SUMMARIZE.LEN.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options.SUMMARIZE.SEPARATOR) {
|
|
||||||
// args.push('SEPARATOR', options.SUMMARIZE.SEPARATOR);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.HIGHLIGHT) {
|
|
||||||
// args.push('HIGHLIGHT');
|
|
||||||
|
|
||||||
// if (typeof options.HIGHLIGHT === 'object') {
|
|
||||||
// if (options.HIGHLIGHT.FIELDS) {
|
|
||||||
// args.push('FIELDS');
|
|
||||||
// pushVariadicArgument(args, options.HIGHLIGHT.FIELDS);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options.HIGHLIGHT.TAGS) {
|
|
||||||
// args.push('TAGS', options.HIGHLIGHT.TAGS.open, options.HIGHLIGHT.TAGS.close);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.SLOP) {
|
|
||||||
// args.push('SLOP', options.SLOP.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.INORDER) {
|
|
||||||
// args.push('INORDER');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.LANGUAGE) {
|
|
||||||
// args.push('LANGUAGE', options.LANGUAGE);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.EXPANDER) {
|
|
||||||
// args.push('EXPANDER', options.EXPANDER);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.SCORER) {
|
|
||||||
// args.push('SCORER', options.SCORER);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if (options?.EXPLAINSCORE) {
|
|
||||||
// // args.push('EXPLAINSCORE');
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // if (options?.PAYLOAD) {
|
|
||||||
// // args.push('PAYLOAD', options.PAYLOAD);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// if (options?.SORTBY) {
|
|
||||||
// args.push('SORTBY');
|
|
||||||
// pushSortByProperty(args, options.SORTBY);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if (options?.MSORTBY) {
|
|
||||||
// // pushSortByArguments(args, 'MSORTBY', options.MSORTBY);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// if (options?.LIMIT) {
|
|
||||||
// args.push(
|
|
||||||
// 'LIMIT',
|
|
||||||
// options.LIMIT.from.toString(),
|
|
||||||
// options.LIMIT.size.toString()
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.PARAMS) {
|
|
||||||
// pushParamsArgs(args, options.PARAMS);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.DIALECT) {
|
|
||||||
// args.push('DIALECT', options.DIALECT.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.RETURN?.length === 0) {
|
|
||||||
// args.preserve = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (options?.TIMEOUT !== undefined) {
|
|
||||||
// args.push('TIMEOUT', options.TIMEOUT.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return args;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// interface SearchDocumentValue {
|
|
||||||
// [key: string]: string | number | null | Array<SearchDocumentValue> | SearchDocumentValue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export interface SearchReply {
|
|
||||||
// total: number;
|
|
||||||
// documents: Array<{
|
|
||||||
// id: string;
|
|
||||||
// value: SearchDocumentValue;
|
|
||||||
// }>;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export interface ProfileOptions {
|
|
||||||
// LIMITED?: true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export type ProfileRawReply<T> = [
|
|
||||||
// results: T,
|
|
||||||
// profile: [
|
|
||||||
// _: string,
|
|
||||||
// TotalProfileTime: string,
|
|
||||||
// _: string,
|
|
||||||
// ParsingTime: string,
|
|
||||||
// _: string,
|
|
||||||
// PipelineCreationTime: string,
|
|
||||||
// _: string,
|
|
||||||
// IteratorsProfile: Array<any>
|
|
||||||
// ]
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// export interface ProfileReply {
|
|
||||||
// results: SearchReply | AGGREGATE.AggregateReply;
|
|
||||||
// profile: ProfileData;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// interface ChildIterator {
|
|
||||||
// type?: string,
|
|
||||||
// counter?: number,
|
|
||||||
// term?: string,
|
|
||||||
// size?: number,
|
|
||||||
// time?: string,
|
|
||||||
// childIterators?: Array<ChildIterator>
|
|
||||||
// }
|
|
||||||
|
|
||||||
// interface IteratorsProfile {
|
|
||||||
// type?: string,
|
|
||||||
// counter?: number,
|
|
||||||
// queryType?: string,
|
|
||||||
// time?: string,
|
|
||||||
// childIterators?: Array<ChildIterator>
|
|
||||||
// }
|
|
||||||
|
|
||||||
// interface ProfileData {
|
|
||||||
// totalProfileTime: string,
|
|
||||||
// parsingTime: string,
|
|
||||||
// pipelineCreationTime: string,
|
|
||||||
// iteratorsProfile: IteratorsProfile
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function transformProfile(reply: Array<any>): ProfileData {
|
|
||||||
// return {
|
|
||||||
// totalProfileTime: reply[0][1],
|
|
||||||
// parsingTime: reply[1][1],
|
|
||||||
// pipelineCreationTime: reply[2][1],
|
|
||||||
// iteratorsProfile: transformIterators(reply[3][1])
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function transformIterators(IteratorsProfile: Array<any>): IteratorsProfile {
|
|
||||||
// var res: IteratorsProfile = {};
|
|
||||||
// for (let i = 0; i < IteratorsProfile.length; i += 2) {
|
|
||||||
// const value = IteratorsProfile[i + 1];
|
|
||||||
// switch (IteratorsProfile[i]) {
|
|
||||||
// case 'Type':
|
|
||||||
// res.type = value;
|
|
||||||
// break;
|
|
||||||
// case 'Counter':
|
|
||||||
// res.counter = value;
|
|
||||||
// break;
|
|
||||||
// case 'Time':
|
|
||||||
// res.time = value;
|
|
||||||
// break;
|
|
||||||
// case 'Query type':
|
|
||||||
// res.queryType = value;
|
|
||||||
// break;
|
|
||||||
// case 'Child iterators':
|
|
||||||
// res.childIterators = value.map(transformChildIterators);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return res;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function transformChildIterators(IteratorsProfile: Array<any>): ChildIterator {
|
|
||||||
// var res: ChildIterator = {};
|
|
||||||
// for (let i = 1; i < IteratorsProfile.length; i += 2) {
|
|
||||||
// const value = IteratorsProfile[i + 1];
|
|
||||||
// switch (IteratorsProfile[i]) {
|
|
||||||
// case 'Type':
|
|
||||||
// res.type = value;
|
|
||||||
// break;
|
|
||||||
// case 'Counter':
|
|
||||||
// res.counter = value;
|
|
||||||
// break;
|
|
||||||
// case 'Time':
|
|
||||||
// res.time = value;
|
|
||||||
// break;
|
|
||||||
// case 'Size':
|
|
||||||
// res.size = value;
|
|
||||||
// break;
|
|
||||||
// case 'Term':
|
|
||||||
// res.term = value;
|
|
||||||
// break;
|
|
||||||
// case 'Child iterators':
|
|
||||||
// res.childIterators = value.map(transformChildIterators);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return res;
|
|
||||||
// }
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"!dist/tsconfig.tsbuildinfo"
|
"!dist/tsconfig.tsbuildinfo"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "*"
|
"@redis/client": "*"
|
||||||
|
@@ -46,7 +46,7 @@ export interface RedisServerDocker {
|
|||||||
dockerId: string;
|
dockerId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extrea ".." cause it'll be in `./dist`
|
// extra ".." cause it'll be in `./dist`
|
||||||
const DOCKER_FODLER_PATH = path.join(__dirname, '../../docker');
|
const DOCKER_FODLER_PATH = path.join(__dirname, '../../docker');
|
||||||
|
|
||||||
async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfig, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfig, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
export { default } from './commands';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
TIME_SERIES_ENCODING,
|
default,
|
||||||
TimeSeriesEncoding,
|
TIME_SERIES_ENCODING, TimeSeriesEncoding,
|
||||||
TIME_SERIES_DUPLICATE_POLICIES,
|
TIME_SERIES_DUPLICATE_POLICIES, TimeSeriesDuplicatePolicies
|
||||||
TimeSeriesDuplicatePolicies
|
|
||||||
} from './commands';
|
} from './commands';
|
||||||
|
|
||||||
export { TIME_SERIES_AGGREGATION_TYPE, TimeSeriesAggregationType } from './commands/CREATERULE';
|
export { TIME_SERIES_AGGREGATION_TYPE, TimeSeriesAggregationType } from './commands/CREATERULE';
|
||||||
export { TIME_SERIES_BUCKET_TIMESTAMP, TimeSeriesBucketTimestamp } from './commands/RANGE';
|
export { TIME_SERIES_BUCKET_TIMESTAMP, TimeSeriesBucketTimestamp } from './commands/RANGE';
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"!dist/tsconfig.tsbuildinfo"
|
"!dist/tsconfig.tsbuildinfo"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"
|
"test": "nyc -r text-summary -r lcov mocha -r tsx './lib/**/*.spec.ts'"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "*"
|
"@redis/client": "*"
|
||||||
|
@@ -1,12 +1,18 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/node18/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ES2022",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"target": "ES2022",
|
||||||
|
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"allowJs": true
|
"allowJs": true
|
||||||
},
|
|
||||||
"ts-node": {
|
|
||||||
"files": true,
|
|
||||||
"transpileOnly": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user