diff --git a/packages/search/lib/commands/SUGGET.ts b/packages/search/lib/commands/SUGGET.ts index 2dc360da3e..9359920fcb 100644 --- a/packages/search/lib/commands/SUGGET.ts +++ b/packages/search/lib/commands/SUGGET.ts @@ -1,4 +1,4 @@ -import { ArrayReply, BlobStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; +import { NullReply, ArrayReply, BlobStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types'; export interface FtSugGetOptions { FUZZY?: boolean; @@ -21,5 +21,5 @@ export default { return args; }, - transformReply: undefined as unknown as () => ArrayReply + transformReply: undefined as unknown as () => NullReply | ArrayReply } as const satisfies Command; diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts index 2151c678c6..42a427ce1f 100644 --- a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts @@ -1,33 +1,35 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './SUGGET_WITHPAYLOADS'; +import SUGGET_WITHPAYLOADS from './SUGGET_WITHPAYLOADS'; -describe('SUGGET WITHPAYLOADS', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('key', 'prefix'), - ['FT.SUGGET', 'key', 'prefix', 'WITHPAYLOADS'] - ); - }); +describe('FT.SUGGET WITHPAYLOADS', () => { + it('transformArguments', () => { + assert.deepEqual( + SUGGET_WITHPAYLOADS.transformArguments('key', 'prefix'), + ['FT.SUGGET', 'key', 'prefix', 'WITHPAYLOADS'] + ); + }); - describe('client.ft.sugGetWithPayloads', () => { - testUtils.testWithClient('null', async client => { - assert.equal( - await client.ft.sugGetWithPayloads('key', 'prefix'), - null - ); - }, GLOBAL.SERVERS.OPEN); + describe('client.ft.sugGetWithPayloads', () => { + testUtils.testWithClient('null', async client => { + assert.equal( + await client.ft.sugGetWithPayloads('key', 'prefix'), + null + ); + }, GLOBAL.SERVERS.OPEN); - testUtils.testWithClient('with suggestions', async client => { - await client.ft.sugAdd('key', 'string', 1, { PAYLOAD: 'payload' }); + testUtils.testWithClient('with suggestions', async client => { + const [, reply] = await Promise.all([ + client.ft.sugAdd('key', 'string', 1, { + PAYLOAD: 'payload' + }), + client.ft.sugGetWithPayloads('key', 'string') + ]); - assert.deepEqual( - await client.ft.sugGetWithPayloads('key', 'string'), - [{ - suggestion: 'string', - payload: 'payload' - }] - ); - }, GLOBAL.SERVERS.OPEN); - }); + assert.deepEqual(reply, [{ + suggestion: 'string', + payload: 'payload' + }]); + }, GLOBAL.SERVERS.OPEN); + }); }); diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts index 7eaff4697e..d8b097f3db 100644 --- a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts +++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts @@ -1,29 +1,31 @@ -import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET'; +import { NullReply, ArrayReply, BlobStringReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { isNullReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import SUGGET from './SUGGET'; -export { IS_READ_ONLY } from './SUGGET'; +export default { + FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, + IS_READ_ONLY: SUGGET.IS_READ_ONLY, + transformArguments(...args: Parameters) { + const transformedArguments = SUGGET.transformArguments(...args); + transformedArguments.push('WITHPAYLOADS'); + return transformedArguments; + }, + transformReply(reply: NullReply | UnwrapReply>) { + if (isNullReply(reply)) return null; -export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array { - return [ - ...transformSugGetArguments(key, prefix, options), - 'WITHPAYLOADS' - ]; -} - -export interface SuggestionWithPayload { - suggestion: string; - payload: string | null; -} - -export function transformReply(rawReply: Array | null): Array | null { - if (rawReply === null) return null; - - const transformedReply = []; - for (let i = 0; i < rawReply.length; i += 2) { - transformedReply.push({ - suggestion: rawReply[i]!, - payload: rawReply[i + 1] - }); + const transformedReply: Array<{ + suggestion: BlobStringReply; + payload: BlobStringReply; + }> = new Array(reply.length / 2); + let replyIndex = 0, + arrIndex = 0; + while (replyIndex < reply.length) { + transformedReply[arrIndex++] = { + suggestion: reply[replyIndex++], + payload: reply[replyIndex++] + }; } return transformedReply; -} + } +} as const satisfies Command; diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts index 41ee055ae7..6969be7729 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts @@ -1,33 +1,33 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './SUGGET_WITHSCORES'; +import SUGGET_WITHSCORES from './SUGGET_WITHSCORES'; -describe('SUGGET WITHSCORES', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('key', 'prefix'), - ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES'] - ); - }); +describe('FT.SUGGET WITHSCORES', () => { + it('transformArguments', () => { + assert.deepEqual( + SUGGET_WITHSCORES.transformArguments('key', 'prefix'), + ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES'] + ); + }); - describe('client.ft.sugGetWithScores', () => { - testUtils.testWithClient('null', async client => { - assert.equal( - await client.ft.sugGetWithScores('key', 'prefix'), - null - ); - }, GLOBAL.SERVERS.OPEN); + describe('client.ft.sugGetWithScores', () => { + testUtils.testWithClient('null', async client => { + assert.equal( + await client.ft.sugGetWithScores('key', 'prefix'), + null + ); + }, GLOBAL.SERVERS.OPEN); - testUtils.testWithClient('with suggestions', async client => { - await client.ft.sugAdd('key', 'string', 1); + testUtils.testWithClient('with suggestions', async client => { + const [, reply] = await Promise.all([ + client.ft.sugAdd('key', 'string', 1), + client.ft.sugGetWithScores('key', 's') + ]); - assert.deepEqual( - await client.ft.sugGetWithScores('key', 'string'), - [{ - suggestion: 'string', - score: 2147483648 - }] - ); - }, GLOBAL.SERVERS.OPEN); - }); + assert.ok(Array.isArray(reply)); + assert.equal(reply.length, 1); + assert.equal(reply[0].suggestion, 'string'); + assert.equal(typeof reply[0].score, 'number'); + }, GLOBAL.SERVERS.OPEN); + }); }); diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.ts index bad5bff299..ccd08de4e7 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES.ts @@ -1,29 +1,51 @@ -import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET'; +import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { isNullReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import SUGGET from './SUGGET'; -export { IS_READ_ONLY } from './SUGGET'; +export default { + FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, + IS_READ_ONLY: SUGGET.IS_READ_ONLY, + transformArguments(...args: Parameters) { + const transformedArguments = SUGGET.transformArguments(...args); + transformedArguments.push('WITHSCORES'); + return transformedArguments; + }, + transformReply: { + 2(reply: NullReply | UnwrapReply>) { + if (isNullReply(reply)) return null; -export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array { - return [ - ...transformSugGetArguments(key, prefix, options), - 'WITHSCORES' - ]; -} + const transformedReply: Array<{ + suggestion: BlobStringReply; + score: number; + }> = new Array(reply.length / 2); + let replyIndex = 0, + arrIndex = 0; + while (replyIndex < reply.length) { + transformedReply[arrIndex++] = { + suggestion: reply[replyIndex++], + score: Number(reply[replyIndex++]) + }; + } -export interface SuggestionWithScores { - suggestion: string; - score: number; -} + return transformedReply; + }, + 3(reply: UnwrapReply>) { + if (isNullReply(reply)) return null; + + const transformedReply: Array<{ + suggestion: BlobStringReply; + score: DoubleReply; + }> = new Array(reply.length / 2); + let replyIndex = 0, + arrIndex = 0; + while (replyIndex < reply.length) { + transformedReply[arrIndex++] = { + suggestion: reply[replyIndex++] as BlobStringReply, + score: reply[replyIndex++] as DoubleReply + }; + } -export function transformReply(rawReply: Array | null): Array | null { - if (rawReply === null) return null; - - const transformedReply = []; - for (let i = 0; i < rawReply.length; i += 2) { - transformedReply.push({ - suggestion: rawReply[i], - score: Number(rawReply[i + 1]) - }); + return transformedReply; } - - return transformedReply; -} + } +} as const satisfies Command; diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts index 8adc9ba2b1..98aad1c802 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts @@ -1,34 +1,36 @@ import { strict as assert } from 'node:assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './SUGGET_WITHSCORES_WITHPAYLOADS'; +import SUGGET_WITHSCORES_WITHPAYLOADS from './SUGGET_WITHSCORES_WITHPAYLOADS'; -describe('SUGGET WITHSCORES WITHPAYLOADS', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('key', 'prefix'), - ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES', 'WITHPAYLOADS'] - ); - }); +describe('FT.SUGGET WITHSCORES WITHPAYLOADS', () => { + it('transformArguments', () => { + assert.deepEqual( + SUGGET_WITHSCORES_WITHPAYLOADS.transformArguments('key', 'prefix'), + ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES', 'WITHPAYLOADS'] + ); + }); - describe('client.ft.sugGetWithScoresWithPayloads', () => { - testUtils.testWithClient('null', async client => { - assert.equal( - await client.ft.sugGetWithScoresWithPayloads('key', 'prefix'), - null - ); - }, GLOBAL.SERVERS.OPEN); + describe('client.ft.sugGetWithScoresWithPayloads', () => { + testUtils.testWithClient('null', async client => { + assert.equal( + await client.ft.sugGetWithScoresWithPayloads('key', 'prefix'), + null + ); + }, GLOBAL.SERVERS.OPEN); - testUtils.testWithClient('with suggestions', async client => { - await client.ft.sugAdd('key', 'string', 1, { PAYLOAD: 'payload' }); + testUtils.testWithClient('with suggestions', async client => { + const [, reply] = await Promise.all([ + client.ft.sugAdd('key', 'string', 1, { + PAYLOAD: 'payload' + }), + client.ft.sugGetWithScoresWithPayloads('key', 'string') + ]); - assert.deepEqual( - await client.ft.sugGetWithScoresWithPayloads('key', 'string'), - [{ - suggestion: 'string', - score: 2147483648, - payload: 'payload' - }] - ); - }, GLOBAL.SERVERS.OPEN); - }); + assert.ok(Array.isArray(reply)); + assert.equal(reply.length, 1); + assert.equal(reply[0].suggestion, 'string'); + assert.equal(typeof reply[0].score, 'number'); + assert.equal(reply[0].payload, 'payload'); + }, GLOBAL.SERVERS.OPEN); + }); }); diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts index 3b2fe7667b..b4b5553bc6 100644 --- a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts +++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts @@ -1,30 +1,58 @@ -import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET'; -import { SuggestionWithPayload } from './SUGGET_WITHPAYLOADS'; -import { SuggestionWithScores } from './SUGGET_WITHSCORES'; +import { NullReply, ArrayReply, BlobStringReply, DoubleReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types'; +import { isNullReply } from '@redis/client/dist/lib/commands/generic-transformers'; +import SUGGET from './SUGGET'; -export { IS_READ_ONLY } from './SUGGET'; +export default { + FIRST_KEY_INDEX: SUGGET.FIRST_KEY_INDEX, + IS_READ_ONLY: SUGGET.IS_READ_ONLY, + transformArguments(...args: Parameters) { + const transformedArguments = SUGGET.transformArguments(...args); + transformedArguments.push( + 'WITHSCORES', + 'WITHPAYLOADS' + ); + return transformedArguments; + }, + transformReply: { + 2(reply: NullReply | UnwrapReply>) { + if (isNullReply(reply)) return null; -export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array { - return [ - ...transformSugGetArguments(key, prefix, options), - 'WITHSCORES', - 'WITHPAYLOADS' - ]; -} + const transformedReply: Array<{ + suggestion: BlobStringReply; + score: number; + payload: BlobStringReply; + }> = new Array(reply.length / 3); + let replyIndex = 0, + arrIndex = 0; + while (replyIndex < reply.length) { + transformedReply[arrIndex++] = { + suggestion: reply[replyIndex++], + score: Number(reply[replyIndex++]), + payload: reply[replyIndex++] + }; + } -type SuggestionWithScoresAndPayloads = SuggestionWithScores & SuggestionWithPayload; + return transformedReply; + }, + 3(reply: NullReply | UnwrapReply>) { + if (isNullReply(reply)) return null; -export function transformReply(rawReply: Array | null): Array | null { - if (rawReply === null) return null; + const transformedReply: Array<{ + suggestion: BlobStringReply; + score: DoubleReply; + payload: BlobStringReply; + }> = new Array(reply.length / 3); + let replyIndex = 0, + arrIndex = 0; + while (replyIndex < reply.length) { + transformedReply[arrIndex++] = { + suggestion: reply[replyIndex++] as BlobStringReply, + score: reply[replyIndex++] as DoubleReply, + payload: reply[replyIndex++] as BlobStringReply + }; + } - const transformedReply = []; - for (let i = 0; i < rawReply.length; i += 3) { - transformedReply.push({ - suggestion: rawReply[i]!, - score: Number(rawReply[i + 1]!), - payload: rawReply[i + 2] - }); + return transformedReply; } - - return transformedReply; -} + } +} as const satisfies Command; diff --git a/packages/search/lib/commands/index.ts b/packages/search/lib/commands/index.ts index 7ff8074350..ccf72e8f4c 100644 --- a/packages/search/lib/commands/index.ts +++ b/packages/search/lib/commands/index.ts @@ -23,9 +23,9 @@ import EXPLAINCLI from './EXPLAINCLI'; import SPELLCHECK from './SPELLCHECK'; import SUGADD from './SUGADD'; import SUGDEL from './SUGDEL'; -// import SUGGET_WITHPAYLOADS from './SUGGET_WITHPAYLOADS'; -// import SUGGET_WITHSCORES_WITHPAYLOADS from './SUGGET_WITHSCORES_WITHPAYLOADS'; -// import SUGGET_WITHSCORES from './SUGGET_WITHSCORES'; +import SUGGET_WITHPAYLOADS from './SUGGET_WITHPAYLOADS'; +import SUGGET_WITHSCORES_WITHPAYLOADS from './SUGGET_WITHSCORES_WITHPAYLOADS'; +import SUGGET_WITHSCORES from './SUGGET_WITHSCORES'; import SUGGET from './SUGGET'; import SUGLEN from './SUGLEN'; import SYNDUMP from './SYNDUMP'; @@ -87,12 +87,12 @@ export default { sugAdd: SUGADD, SUGDEL, sugDel: SUGDEL, - // SUGGET_WITHPAYLOADS, - // sugGetWithPayloads: SUGGET_WITHPAYLOADS, - // SUGGET_WITHSCORES_WITHPAYLOADS, - // sugGetWithScoresWithPayloads: SUGGET_WITHSCORES_WITHPAYLOADS, - // SUGGET_WITHSCORES, - // sugGetWithScores: SUGGET_WITHSCORES, + SUGGET_WITHPAYLOADS, + sugGetWithPayloads: SUGGET_WITHPAYLOADS, + SUGGET_WITHSCORES_WITHPAYLOADS, + sugGetWithScoresWithPayloads: SUGGET_WITHSCORES_WITHPAYLOADS, + SUGGET_WITHSCORES, + sugGetWithScores: SUGGET_WITHSCORES, SUGGET, sugGet: SUGGET, SUGLEN,