diff --git a/.github/release-drafter-base.yml b/.github/release-drafter-base.yml index 9a98b1c08a..ea259fc0d2 100644 --- a/.github/release-drafter-base.yml +++ b/.github/release-drafter-base.yml @@ -1,5 +1,5 @@ -name-template: 'Version $NEXT_PATCH_VERSION' -tag-template: 'v$NEXT_PATCH_VERSION' +name-template: 'json@$NEXT_PATCH_VERSION' +tag-template: 'json@$NEXT_PATCH_VERSION' autolabeler: - label: 'chore' files: @@ -28,8 +28,15 @@ categories: - 'bugfix' - 'bug' - title: '🧰 Maintenance' - label: 'chore' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' + change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/json' exclude-labels: - 'skip-changelog' template: | diff --git a/.github/release-drafter/bloom-config.yml b/.github/release-drafter/bloom-config.yml new file mode 100644 index 0000000000..7734330b95 --- /dev/null +++ b/.github/release-drafter/bloom-config.yml @@ -0,0 +1,50 @@ +name-template: 'bloom@$NEXT_PATCH_VERSION' +tag-template: 'bloom@$NEXT_PATCH_VERSION' +autolabeler: + - label: 'chore' + files: + - '*.md' + - '.github/*' + - label: 'bug' + branch: + - '/bug-.+' + - label: 'chore' + branch: + - '/chore-.+' + - label: 'feature' + branch: + - '/feature-.+' +categories: + - title: 'Breaking Changes' + labels: + - 'breakingchange' + - title: 'πŸš€ New Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' + +change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/bloom' +exclude-labels: + - 'skip-changelog' +template: | + ## Changes + + $CHANGES + + ## Contributors + We'd like to thank all the contributors who worked on this release! + + $CONTRIBUTORS diff --git a/.github/release-drafter/graph-config.yml b/.github/release-drafter/graph-config.yml new file mode 100644 index 0000000000..88d76b78b5 --- /dev/null +++ b/.github/release-drafter/graph-config.yml @@ -0,0 +1,49 @@ +name-template: 'graph@$NEXT_PATCH_VERSION' +tag-template: 'graph@$NEXT_PATCH_VERSION' +autolabeler: + - label: 'chore' + files: + - '*.md' + - '.github/*' + - label: 'bug' + branch: + - '/bug-.+' + - label: 'chore' + branch: + - '/chore-.+' + - label: 'feature' + branch: + - '/feature-.+' +categories: + - title: 'Breaking Changes' + labels: + - 'breakingchange' + - title: 'πŸš€ New Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' +change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/graph' +exclude-labels: + - 'skip-changelog' +template: | + ## Changes + + $CHANGES + + ## Contributors + We'd like to thank all the contributors who worked on this release! + + $CONTRIBUTORS diff --git a/.github/release-drafter/json-config.yml b/.github/release-drafter/json-config.yml new file mode 100644 index 0000000000..ea259fc0d2 --- /dev/null +++ b/.github/release-drafter/json-config.yml @@ -0,0 +1,50 @@ +name-template: 'json@$NEXT_PATCH_VERSION' +tag-template: 'json@$NEXT_PATCH_VERSION' +autolabeler: + - label: 'chore' + files: + - '*.md' + - '.github/*' + - label: 'bug' + branch: + - '/bug-.+' + - label: 'chore' + branch: + - '/chore-.+' + - label: 'feature' + branch: + - '/feature-.+' +categories: + - title: 'Breaking Changes' + labels: + - 'breakingchange' + - title: 'πŸš€ New Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' + +change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/json' +exclude-labels: + - 'skip-changelog' +template: | + ## Changes + + $CHANGES + + ## Contributors + We'd like to thank all the contributors who worked on this release! + + $CONTRIBUTORS diff --git a/.github/release-drafter/search-config.yml b/.github/release-drafter/search-config.yml new file mode 100644 index 0000000000..a78070aa59 --- /dev/null +++ b/.github/release-drafter/search-config.yml @@ -0,0 +1,50 @@ +name-template: 'search@$NEXT_PATCH_VERSION' +tag-template: 'search@$NEXT_PATCH_VERSION' +autolabeler: + - label: 'chore' + files: + - '*.md' + - '.github/*' + - label: 'bug' + branch: + - '/bug-.+' + - label: 'chore' + branch: + - '/chore-.+' + - label: 'feature' + branch: + - '/feature-.+' +categories: + - title: 'Breaking Changes' + labels: + - 'breakingchange' + - title: 'πŸš€ New Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' + +change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/search' +exclude-labels: + - 'skip-changelog' +template: | + ## Changes + + $CHANGES + + ## Contributors + We'd like to thank all the contributors who worked on this release! + + $CONTRIBUTORS diff --git a/.github/release-drafter/time-series-config.yml b/.github/release-drafter/time-series-config.yml new file mode 100644 index 0000000000..29aee0cbc9 --- /dev/null +++ b/.github/release-drafter/time-series-config.yml @@ -0,0 +1,49 @@ +name-template: 'time-series@$NEXT_PATCH_VERSION' +tag-template: 'time-series@$NEXT_PATCH_VERSION' +autolabeler: + - label: 'chore' + files: + - '*.md' + - '.github/*' + - label: 'bug' + branch: + - '/bug-.+' + - label: 'chore' + branch: + - '/chore-.+' + - label: 'feature' + branch: + - '/feature-.+' +categories: + - title: 'Breaking Changes' + labels: + - 'breakingchange' + - title: 'πŸš€ New Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: + - 'chore' + - 'maintenance' + - 'documentation' + - 'docs' +change-template: '- $TITLE (#$NUMBER)' +include-paths: + - 'packages/time-series' +exclude-labels: + - 'skip-changelog' +template: | + ## Changes + + $CHANGES + + ## Contributors + We'd like to thank all the contributors who worked on this release! + + $CONTRIBUTORS diff --git a/.github/workflows/release-drafter-bloom.yml b/.github/workflows/release-drafter-bloom.yml new file mode 100644 index 0000000000..4ad525c058 --- /dev/null +++ b/.github/workflows/release-drafter-bloom.yml @@ -0,0 +1,24 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + + update_release_draft: + + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + with: + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + config-name: release-drafter/bloom-config.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter-graph.yml b/.github/workflows/release-drafter-graph.yml new file mode 100644 index 0000000000..4d664e5f19 --- /dev/null +++ b/.github/workflows/release-drafter-graph.yml @@ -0,0 +1,24 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + + update_release_draft: + + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + with: + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + config-name: release-drafter/graph-config.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter-json.yml similarity index 80% rename from .github/workflows/release-drafter.yml rename to .github/workflows/release-drafter-json.yml index ec2d88bf6e..a8b3ba4d13 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter-json.yml @@ -7,13 +7,18 @@ on: - master jobs: + update_release_draft: + + permissions: + contents: write + pull-requests: write runs-on: ubuntu-latest steps: # Drafts your next Release notes as Pull Requests are merged into "master" - uses: release-drafter/release-drafter@v5 with: # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml - config-name: release-drafter-config.yml + config-name: release-drafter/json-config.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter-search.yml b/.github/workflows/release-drafter-search.yml new file mode 100644 index 0000000000..c331430353 --- /dev/null +++ b/.github/workflows/release-drafter-search.yml @@ -0,0 +1,24 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + + update_release_draft: + + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + with: + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + config-name: release-drafter/search-config.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter-time-series.yml b/.github/workflows/release-drafter-time-series.yml new file mode 100644 index 0000000000..71e44a70fd --- /dev/null +++ b/.github/workflows/release-drafter-time-series.yml @@ -0,0 +1,24 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + + update_release_draft: + + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + with: + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + config-name: release-drafter/time-series-config.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/FAQ.md b/docs/FAQ.md index 77402d4a72..5774213da5 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -10,7 +10,7 @@ If don't want to queue commands in memory until a new socket is established, set ## How are commands batched? -Commands are pipelined using [`setImmediate`](https://nodejs.org/api/globals.html#setimmediatecallback-args). +Commands are pipelined using [`setImmediate`](https://nodejs.org/api/timers.html#setimmediatecallback-args). If `socket.write()` returns `false`β€”meaning that ["all or part of the data was queued in user memory"](https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback:~:text=all%20or%20part%20of%20the%20data%20was%20queued%20in%20user%20memory)β€”the commands will stack in memory until the [`drain`](https://nodejs.org/api/net.html#net_event_drain) event is fired. diff --git a/docs/pub-sub.md b/docs/pub-sub.md index 6d210e2fe1..b319925569 100644 --- a/docs/pub-sub.md +++ b/docs/pub-sub.md @@ -39,7 +39,7 @@ await client.pSubscribe('channe*', listener); await client.sSubscribe('channel', listener); ``` -> NOTE: Subscribing to the same channel more than once will create multiple listeners which will each be called when a message is recieved. +> ⚠️ Subscribing to the same channel more than once will create multiple listeners which will each be called when a message is recieved. ## Publishing diff --git a/examples/search-hashes.js b/examples/search-hashes.js index f0a4560f90..f3aca6b8ae 100644 --- a/examples/search-hashes.js +++ b/examples/search-hashes.js @@ -13,7 +13,7 @@ try { await client.ft.create('idx:animals', { name: { type: SchemaFieldTypes.TEXT, - sortable: true + SORTABLE: true }, species: SchemaFieldTypes.TAG, age: SchemaFieldTypes.NUMERIC diff --git a/package-lock.json b/package-lock.json index 0eaf067a55..064e8729c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -470,7 +470,34 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "version": "2.0.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", @@ -480,6 +507,7 @@ "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.5.2", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -790,6 +818,9 @@ } }, "node_modules/@sinonjs/fake-timers": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", + "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", "version": "10.2.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", @@ -799,6 +830,9 @@ } }, "node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "version": "8.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", @@ -868,12 +902,18 @@ "peer": true }, "node_modules/@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "version": "7.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, "node_modules/@types/sinon": { + "version": "10.0.15", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", + "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", "version": "10.0.15", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", @@ -889,6 +929,9 @@ "dev": true }, "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "version": "17.0.24", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", @@ -1054,6 +1097,7 @@ "integrity": "sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", @@ -1689,6 +1733,10 @@ "eslint-visitor-keys": "^3.4.1", "espree": "^9.5.2", "esquery": "^1.4.2", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -1696,6 +1744,7 @@ "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -1748,6 +1797,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "version": "7.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", @@ -1760,6 +1812,9 @@ "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "funding": { "url": "https://opencollective.com/eslint" } @@ -1775,6 +1830,9 @@ } }, "node_modules/espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "version": "9.5.2", "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", @@ -1784,6 +1842,7 @@ "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2510,6 +2569,22 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": ">=10.13" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -2731,6 +2806,18 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2800,6 +2887,9 @@ "dev": true }, "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", @@ -3717,11 +3807,19 @@ "dev": true }, "node_modules/sinon": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", + "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", "version": "15.1.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", "dev": true, "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.2.0", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.4", "@sinonjs/commons": "^3.0.0", "@sinonjs/fake-timers": "^10.2.0", "@sinonjs/samsam": "^8.0.0", @@ -4033,6 +4131,9 @@ } }, "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", @@ -4040,6 +4141,7 @@ "peer": true, "engines": { "node": ">=10" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4063,6 +4165,8 @@ "lunr": "^2.3.9", "marked": "^4.3.0", "minimatch": "^9.0.0", + "marked": "^4.3.0", + "minimatch": "^9.0.0", "shiki": "^0.14.1" }, "bin": { @@ -4085,6 +4189,9 @@ } }, "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", "version": "9.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", @@ -4094,6 +4201,7 @@ }, "engines": { "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -4472,6 +4580,9 @@ } }, "packages/test-utils/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", @@ -4507,6 +4618,19 @@ "peerDependencies": { "@redis/client": "*" } + }, + "packages/time-series/node_modules/typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } } } } diff --git a/packages/client/lib/commands/LATENCY_GRAPH.spec.ts b/packages/client/lib/commands/LATENCY_GRAPH.spec.ts index df4d5d466a..21755a253b 100644 --- a/packages/client/lib/commands/LATENCY_GRAPH.spec.ts +++ b/packages/client/lib/commands/LATENCY_GRAPH.spec.ts @@ -24,9 +24,5 @@ describe('LATENCY GRAPH', () => { typeof await client.latencyGraph('command'), 'string' ); - }, { - serverArguments: testUtils.isVersionGreaterThan([7]) ? - ['--enable-debug-command', 'yes'] : - GLOBAL.SERVERS.OPEN.serverArguments - }); + }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/LATENCY_LATEST.spec.ts b/packages/client/lib/commands/LATENCY_LATEST.spec.ts new file mode 100644 index 0000000000..4087f21213 --- /dev/null +++ b/packages/client/lib/commands/LATENCY_LATEST.spec.ts @@ -0,0 +1,27 @@ +import {strict as assert} from 'assert'; +import testUtils, {GLOBAL} from '../test-utils'; +import { transformArguments } from './LATENCY_LATEST'; + +describe('LATENCY LATEST', () => { + it('transformArguments', () => { + assert.deepEqual( + transformArguments(), + ['LATENCY', 'LATEST'] + ); + }); + + testUtils.testWithClient('client.latencyLatest', async client => { + await Promise.all([ + client.configSet('latency-monitor-threshold', '100'), + client.sendCommand(['DEBUG', 'SLEEP', '1']) + ]); + const latency = await client.latencyLatest(); + assert.ok(Array.isArray(latency)); + for (const [name, timestamp, latestLatency, allTimeLatency] of latency) { + assert.equal(typeof name, 'string'); + assert.equal(typeof timestamp, 'number'); + assert.equal(typeof latestLatency, 'number'); + assert.equal(typeof allTimeLatency, 'number'); + } + }, GLOBAL.SERVERS.OPEN); +}); diff --git a/packages/client/lib/commands/LATENCY_LATEST.ts b/packages/client/lib/commands/LATENCY_LATEST.ts new file mode 100644 index 0000000000..3e4dd6236c --- /dev/null +++ b/packages/client/lib/commands/LATENCY_LATEST.ts @@ -0,0 +1,12 @@ +import { RedisCommandArguments } from '.'; + +export function transformArguments(): RedisCommandArguments { + return ['LATENCY', 'LATEST']; +} + +export declare function transformReply(): Array<[ + name: string, + timestamp: number, + latestLatency: number, + allTimeLatency: number +]>; diff --git a/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts b/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts index bfbd946bba..64f926dec1 100644 --- a/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts +++ b/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts @@ -13,17 +13,19 @@ // it('transformReply', () => { // assert.deepEqual( // transformReply([ -// ['name', 'Alice', 'pending', 1, 'idle', 9104628], -// ['name', 'Bob', 'pending', 1, 'idle', 83841983] +// ['name', 'Alice', 'pending', 1, 'idle', 9104628, 'inactive', 9281221], +// ['name', 'Bob', 'pending', 1, 'idle', 83841983, 'inactive', 7213871] // ]), // [{ // name: 'Alice', // pending: 1, -// idle: 9104628 +// idle: 9104628, +// inactive: 9281221, // }, { // name: 'Bob', // pending: 1, -// idle: 83841983 +// idle: 83841983, +// inactive: 7213871, // }] // ); // }); diff --git a/packages/client/lib/commands/XINFO_CONSUMERS.ts b/packages/client/lib/commands/XINFO_CONSUMERS.ts index a9c5cb75e4..c6b3b99f18 100644 --- a/packages/client/lib/commands/XINFO_CONSUMERS.ts +++ b/packages/client/lib/commands/XINFO_CONSUMERS.ts @@ -15,12 +15,14 @@ // name: RedisCommandArgument; // pending: number; // idle: number; +// inactive: number; // }>; // export function transformReply(rawReply: Array): XInfoConsumersReply { // return rawReply.map(consumer => ({ // name: consumer[1], // pending: consumer[3], -// idle: consumer[5] +// idle: consumer[5], +// inactive: consumer[7] // })); // } diff --git a/packages/client/lib/test-utils.ts b/packages/client/lib/test-utils.ts index 9032f1dd34..65d526f601 100644 --- a/packages/client/lib/test-utils.ts +++ b/packages/client/lib/test-utils.ts @@ -2,18 +2,24 @@ import TestUtils from '@redis/test-utils'; import { SinonSpy } from 'sinon'; import { promiseTimeout } from './utils'; -export default new TestUtils({ - dockerImageName: 'redis', - dockerImageVersionArgument: 'redis-version' +const utils = new TestUtils({ + dockerImageName: 'redis', + dockerImageVersionArgument: 'redis-version' }); +export default utils; + +const DEBUG_MODE_ARGS = utils.isVersionGreaterThan([7]) ? + ['--enable-debug-command', 'yes'] : + []; + export const GLOBAL = { SERVERS: { OPEN: { - serverArguments: [] + serverArguments: [...DEBUG_MODE_ARGS] }, PASSWORD: { - serverArguments: ['--requirepass', 'password'], + serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS], clientOptions: { password: 'password' } @@ -21,10 +27,10 @@ export const GLOBAL = { }, CLUSTERS: { OPEN: { - serverArguments: [] + serverArguments: [...DEBUG_MODE_ARGS] }, PASSWORD: { - serverArguments: ['--requirepass', 'password'], + serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS], clusterConfiguration: { defaults: { password: 'password' @@ -32,7 +38,7 @@ export const GLOBAL = { } }, WITH_REPLICAS: { - serverArguments: [], + serverArguments: [...DEBUG_MODE_ARGS], numberOfMasters: 2, numberOfReplicas: 1, clusterConfiguration: { diff --git a/packages/graph/lib/graph.spec.ts b/packages/graph/lib/graph.spec.ts index ff45759fe8..495c6d17a8 100644 --- a/packages/graph/lib/graph.spec.ts +++ b/packages/graph/lib/graph.spec.ts @@ -68,7 +68,7 @@ describe('Graph', () => { // check with and without metadata cache for (let i = 0; i < 2; i++) { - const { data } = await graph.query('CREATE ()-[edge :edge]->() RETURN edge'); + const { data } = await graph.query('CREATE ()-[edge :edge]->() RETURN edge'); assert.ok(Array.isArray(data)); assert.equal(data.length, 1); assert.equal(typeof data[0].edge.id, 'number'); @@ -85,7 +85,7 @@ describe('Graph', () => { // check with and without metadata cache for (let i = 0; i < 2; i++) { - const { data } = await graph.query('CREATE (node :node { p: 0 }) RETURN node'); + const { data } = await graph.query('CREATE (node :node { p: 0 }) RETURN node'); assert.ok(Array.isArray(data)); assert.equal(data.length, 1); assert.equal(typeof data[0].node.id, 'number'); @@ -98,7 +98,7 @@ describe('Graph', () => { const graph = new Graph(client as any, 'graph'), [, { data }] = await Promise.all([ await graph.query('CREATE ()-[:edge]->()'), - await graph.roQuery('MATCH path = ()-[:edge]->() RETURN path') + await graph.roQuery('MATCH path = ()-[:edge]->() RETURN path') ]); assert.ok(Array.isArray(data)); diff --git a/packages/json/README.md b/packages/json/README.md index adc125eb98..e7f7017411 100644 --- a/packages/json/README.md +++ b/packages/json/README.md @@ -1,6 +1,6 @@ # @redis/json -This package provides support for the [RedisJSON](https://redisjson.io) module, which adds JSON as a native data type to Redis. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RedisJSON commands. +This package provides support for the [RedisJSON](https://redis.io/docs/stack/json/) module, which adds JSON as a native data type to Redis. It extends the [Node Redis client](https://github.com/redis/node-redis) to include functions for each of the RedisJSON commands. To use these extra commands, your Redis server must have the RedisJSON module installed. @@ -10,7 +10,7 @@ For a complete example, see [`managing-json.js`](https://github.com/redis/node-r ### Storing JSON Documents in Redis -The [`JSON.SET`](https://oss.redis.com/redisjson/commands/#jsonset) command stores a JSON value at a given JSON Path in a Redis key. +The [`JSON.SET`](https://redis.io/commands/json.set/) command stores a JSON value at a given JSON Path in a Redis key. Here, we'll store a JSON document in the root of the Redis key "`mydoc`": @@ -37,11 +37,11 @@ await client.json.set('noderedis:jsondata', '$', { }); ``` -For more information about RedisJSON's path syntax, [check out the documentation](https://oss.redis.com/redisjson/path/). +For more information about RedisJSON's path syntax, [check out the documentation](https://redis.io/docs/stack/json/path/). ### Retrieving JSON Documents from Redis -With RedisJSON, we can retrieve all or part(s) of a JSON document using the [`JSON.GET`]() command and one or more JSON Paths. Let's get the name and age of one of the pets: +With RedisJSON, we can retrieve all or part(s) of a JSON document using the [`JSON.GET`](https://redis.io/commands/json.get/) command and one or more JSON Paths. Let's get the name and age of one of the pets: ```javascript const results = await client.json.get('noderedis:jsondata', { @@ -62,19 +62,19 @@ const results = await client.json.get('noderedis:jsondata', { RedisJSON includes commands that can atomically update values in a JSON document, in place in Redis without having to first retrieve the entire document. -Using the [`JSON.NUMINCRBY`](https://oss.redis.com/redisjson/commands/#jsonnumincrby) command, we can update the age of one of the pets like this: +Using the [`JSON.NUMINCRBY`](https://redis.io/commands/json.numincrby/) command, we can update the age of one of the pets like this: ```javascript await client.json.numIncrBy('noderedis:jsondata', '.pets[1].age', 1); ``` -And we can add a new object to the pets array with the [`JSON.ARRAPPEND`](https://oss.redis.com/redisjson/commands/#jsonarrappend) command: +And we can add a new object to the pets array with the [`JSON.ARRAPPEND`](https://redis.io/commands/json.arrappend/) command: ```javascript - await client.json.arrAppend('noderedis:jsondata', '.pets', { - name: 'Robin', - species: 'bird', - age: 1, - isMammal: false - }); +await client.json.arrAppend('noderedis:jsondata', '.pets', { + name: 'Robin', + species: 'bird', + age: 1, + isMammal: false +}); ``` diff --git a/packages/search/lib/commands/AGGREGATE.spec.ts b/packages/search/lib/commands/AGGREGATE.spec.ts index a233007643..d1e4565339 100644 --- a/packages/search/lib/commands/AGGREGATE.spec.ts +++ b/packages/search/lib/commands/AGGREGATE.spec.ts @@ -454,6 +454,13 @@ describe('AGGREGATE', () => { ['FT.AGGREGATE', 'index', '*', 'DIALECT', '1'] ); }); + + it('with TIMEOUT', () => { + assert.deepEqual( + transformArguments('index', '*', { TIMEOUT: 10 }), + ['FT.AGGREGATE', 'index', '*', 'TIMEOUT', '10'] + ); + }); }); testUtils.testWithClient('client.ft.aggregate', async client => { diff --git a/packages/search/lib/commands/AGGREGATE.ts b/packages/search/lib/commands/AGGREGATE.ts index fb831f54bc..6739581538 100644 --- a/packages/search/lib/commands/AGGREGATE.ts +++ b/packages/search/lib/commands/AGGREGATE.ts @@ -124,6 +124,7 @@ export interface AggregateOptions { STEPS?: Array; PARAMS?: Params; DIALECT?: number; + TIMEOUT?: number; } export const FIRST_KEY_INDEX = 1; @@ -213,6 +214,10 @@ export function pushAggregatehOptions( args.push('DIALECT', options.DIALECT.toString()); } + if (options?.TIMEOUT !== undefined) { + args.push('TIMEOUT', options.TIMEOUT.toString()); + } + return args; } diff --git a/packages/search/lib/commands/CURSOR_READ.spec.ts b/packages/search/lib/commands/CURSOR_READ.spec.ts index 5b4f4122d4..bb68e2b639 100644 --- a/packages/search/lib/commands/CURSOR_READ.spec.ts +++ b/packages/search/lib/commands/CURSOR_READ.spec.ts @@ -4,15 +4,24 @@ import testUtils, { GLOBAL } from '../test-utils'; import { transformArguments } from './CURSOR_READ'; describe('CURSOR READ', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('index', 0), - ['FT.CURSOR', 'READ', 'index', '0'] - ); + describe('transformArguments', () => { + it('without options', () => { + assert.deepEqual( + transformArguments('index', 0), + ['FT.CURSOR', 'READ', 'index', '0'] + ); + }); + + it('with COUNT', () => { + assert.deepEqual( + transformArguments('index', 0, { COUNT: 1 }), + ['FT.CURSOR', 'READ', 'index', '0', 'COUNT', '1'] + ); + }); }); testUtils.testWithClient('client.ft.cursorRead', async client => { - const [ ,, { cursor } ] = await Promise.all([ + const [, , { cursor }] = await Promise.all([ client.ft.create('idx', { field: { type: SchemaFieldTypes.TEXT diff --git a/packages/search/lib/commands/CURSOR_READ.ts b/packages/search/lib/commands/CURSOR_READ.ts index 1e828cc3e4..35cf1bc4f0 100644 --- a/packages/search/lib/commands/CURSOR_READ.ts +++ b/packages/search/lib/commands/CURSOR_READ.ts @@ -4,16 +4,27 @@ export const FIRST_KEY_INDEX = 1; export const IS_READ_ONLY = true; +interface CursorReadOptions { + COUNT?: number; +} + export function transformArguments( index: RedisCommandArgument, - cursor: number + cursor: number, + options?: CursorReadOptions ): RedisCommandArguments { - return [ + const args = [ 'FT.CURSOR', 'READ', index, cursor.toString() ]; + + if (options?.COUNT) { + args.push('COUNT', options.COUNT.toString()); + } + + return args; } export { transformReply } from './AGGREGATE_WITHCURSOR'; diff --git a/packages/search/lib/commands/SEARCH.spec.ts b/packages/search/lib/commands/SEARCH.spec.ts index 47c82cf892..931458b3a2 100644 --- a/packages/search/lib/commands/SEARCH.spec.ts +++ b/packages/search/lib/commands/SEARCH.spec.ts @@ -233,6 +233,15 @@ describe('SEARCH', () => { ['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', () => { diff --git a/packages/search/lib/commands/SEARCH.ts b/packages/search/lib/commands/SEARCH.ts index fbccb25058..ef6c0d5c2d 100644 --- a/packages/search/lib/commands/SEARCH.ts +++ b/packages/search/lib/commands/SEARCH.ts @@ -55,6 +55,7 @@ export interface SearchOptions { }; PARAMS?: Params; DIALECT?: number; + TIMEOUT?: number; } export function transformArguments( diff --git a/packages/search/lib/commands/index.ts b/packages/search/lib/commands/index.ts index f3fb16d702..82808605de 100644 --- a/packages/search/lib/commands/index.ts +++ b/packages/search/lib/commands/index.ts @@ -510,6 +510,10 @@ export function pushSearchOptions( args.preserve = true; } + if (options?.TIMEOUT !== undefined) { + args.push('TIMEOUT', options.TIMEOUT.toString()); + } + return args; } diff --git a/packages/search/package.json b/packages/search/package.json index d1562d58fa..29cb9fc8c4 100644 --- a/packages/search/package.json +++ b/packages/search/package.json @@ -1,6 +1,6 @@ { "name": "@redis/search", - "version": "1.1.2", + "version": "1.1.3", "license": "MIT", "main": "./dist/index.js", "types": "./dist/index.d.ts",