1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

some RediSearch commands

This commit is contained in:
Leibale
2023-07-31 17:34:45 -04:00
parent 689c6a576c
commit cf38f512b8
34 changed files with 456 additions and 372 deletions

View File

@@ -182,6 +182,7 @@ Some command arguments/replies have changed to align more closely to data types
- `JSON.DEL`: `path` argument moved to `{ path: string; }` [^future-proofing]
- `JSON.FORGET`: `path` argument moved to `{ path: string; }` [^future-proofing]
- `TS.[M][REV]RANGE`: `enum TimeSeriesBucketTimestamp` -> `const TIME_SERIES_BUCKET_TIMESTAMP` [^enum-to-constants], `enum TimeSeriesReducers` -> `const TIME_SERIES_REDUCERS` [^enum-to-constants], the `ALIGN` argument has been moved into `AGGREGRATION`
- `TS.SYNUPDATE`: `Array<string | Array<string>>` -> `Record<string, Array<string>>`
[^enum-to-constants]: TODO

View File

@@ -1,11 +1,24 @@
import { strict as assert } from 'assert';
import { transformArguments } from './ALIASADD';
import testUtils, { GLOBAL } from '../test-utils';
import ALIASADD from './ALIASADD';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('ALIASADD', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('alias', 'index'),
['FT.ALIASADD', 'alias', 'index']
);
});
describe('FT.ALIASADD', () => {
it('transformArguments', () => {
assert.deepEqual(
ALIASADD.transformArguments('alias', 'index'),
['FT.ALIASADD', 'alias', 'index']
);
});
testUtils.testWithClient('client.ft.aliasAdd', async client => {
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.aliasAdd('alias', 'index')
]);
assert.equal(reply, 'OK');
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,5 +1,10 @@
export function transformArguments(name: string, index: string): Array<string> {
return ['FT.ALIASADD', name, index];
}
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
export declare function transformReply(): 'OK';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(alias: RedisArgument, index: RedisArgument) {
return ['FT.ALIASADD', alias, index];
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
} as const satisfies Command;

View File

@@ -1,11 +1,25 @@
import { strict as assert } from 'assert';
import { transformArguments } from './ALIASDEL';
import testUtils, { GLOBAL } from '../test-utils';
import ALIASDEL from './ALIASDEL';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('ALIASDEL', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('alias', 'index'),
['FT.ALIASDEL', 'alias', 'index']
);
});
describe('FT.ALIASDEL', () => {
it('transformArguments', () => {
assert.deepEqual(
ALIASDEL.transformArguments('alias'),
['FT.ALIASDEL', 'alias']
);
});
testUtils.testWithClient('client.ft.aliasAdd', async client => {
const [, , reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.aliasAdd('alias', 'index'),
client.ft.aliasDel('alias')
]);
assert.equal(reply, 'OK');
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,5 +1,10 @@
export function transformArguments(name: string, index: string): Array<string> {
return ['FT.ALIASDEL', name, index];
}
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
export declare function transformReply(): 'OK';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(alias: RedisArgument) {
return ['FT.ALIASDEL', alias];
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
} as const satisfies Command;

View File

@@ -1,11 +1,24 @@
import { strict as assert } from 'assert';
import { transformArguments } from './ALIASUPDATE';
import testUtils, { GLOBAL } from '../test-utils';
import ALIASUPDATE from './ALIASUPDATE';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('ALIASUPDATE', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('alias', 'index'),
['FT.ALIASUPDATE', 'alias', 'index']
);
});
describe('FT.ALIASUPDATE', () => {
it('transformArguments', () => {
assert.deepEqual(
ALIASUPDATE.transformArguments('alias', 'index'),
['FT.ALIASUPDATE', 'alias', 'index']
);
});
testUtils.testWithClient('client.ft.aliasUpdate', async client => {
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.aliasUpdate('alias', 'index')
]);
assert.equal(reply, 'OK');
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,5 +1,10 @@
export function transformArguments(name: string, index: string): Array<string> {
return ['FT.ALIASUPDATE', name, index];
}
import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
export declare function transformReply(): 'OK';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(alias: RedisArgument, index: RedisArgument) {
return ['FT.ALIASUPDATE', alias, index];
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
} as const satisfies Command;

View File

@@ -257,8 +257,8 @@ export interface CreateOptions {
}
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument, schema: RediSearchSchema, options?: CreateOptions) {
const args = ['FT.CREATE', index];

View File

@@ -1,33 +1,32 @@
import { strict as assert } from 'assert';
import { SchemaFieldTypes } from '.';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CURSOR_DEL';
import CURSOR_DEL from './CURSOR_DEL';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('CURSOR DEL', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('index', 0),
['FT.CURSOR', 'DEL', 'index', '0']
);
});
describe('FT.CURSOR DEL', () => {
it('transformArguments', () => {
assert.deepEqual(
CURSOR_DEL.transformArguments('index', '0'),
['FT.CURSOR', 'DEL', 'index', '0']
);
});
testUtils.testWithClient('client.ft.cursorDel', async client => {
const [ ,, { cursor } ] = await Promise.all([
client.ft.create('idx', {
field: {
type: SchemaFieldTypes.TEXT
}
}),
client.hSet('key', 'field', 'value'),
client.ft.aggregateWithCursor('idx', '*', {
COUNT: 1
})
]);
testUtils.testWithClient('client.ft.cursorDel', async client => {
const [, , { cursor }] = await Promise.all([
client.ft.create('idx', {
field: {
type: SCHEMA_FIELD_TYPE.TEXT
}
}),
client.hSet('key', 'field', 'value'),
client.ft.aggregateWithCursor('idx', '*', {
COUNT: 1
})
]);
assert.equal(
await client.ft.cursorDel('idx', cursor),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
assert.equal(
await client.ft.cursorDel('idx', cursor),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,14 +1,10 @@
import { RedisCommandArgument } from '@redis/client/dist/lib/commands';
import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
export const FIRST_KEY_INDEX = 1;
export function transformArguments(index: RedisCommandArgument, cursorId: number) {
return [
'FT.CURSOR',
'DEL',
index,
cursorId.toString()
];
}
export declare function transformReply(): 'OK';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument, cursorId: RedisArgument) {
return ['FT.CURSOR', 'DEL', index, cursorId];
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
} as const satisfies Command;

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import DICTADD from './DICTADD';
describe('DICTADD', () => {
describe('FT.DICTADD', () => {
describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(

View File

@@ -3,7 +3,7 @@ import { pushVariadicArguments, RedisVariadicArgument } from '@redis/client/dist
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(dictionary: RedisArgument, term: RedisVariadicArgument) {
return pushVariadicArguments(['FT.DICTADD', dictionary], term);
},

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import DICTDEL from './DICTDEL';
describe('DICTDEL', () => {
describe('FT.DICTDEL', () => {
describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(

View File

@@ -3,7 +3,7 @@ import { pushVariadicArguments, RedisVariadicArgument } from '@redis/client/dist
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(dictionary: RedisArgument, term: RedisVariadicArgument) {
return pushVariadicArguments(['FT.DICTDEL', dictionary], term);
},

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import DICTDUMP from './DICTDUMP';
describe('DICTDUMP', () => {
describe('FT.DICTDUMP', () => {
it('transformArguments', () => {
assert.deepEqual(
DICTDUMP.transformArguments('dictionary'),
@@ -11,11 +11,11 @@ describe('DICTDUMP', () => {
});
testUtils.testWithClient('client.ft.dictDump', async client => {
await client.ft.dictAdd('dictionary', 'string')
const [, reply] = await Promise.all([
client.ft.dictAdd('dictionary', 'string'),
client.ft.dictDump('dictionary')
]);
assert.deepEqual(
await client.ft.dictDump('dictionary'),
['string']
);
assert.deepEqual(reply, ['string']);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,9 +1,9 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { SchemaFieldTypes } from '.';
import DROPINDEX from './DROPINDEX';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('DROPINDEX', () => {
describe('FT.DROPINDEX', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(
@@ -21,13 +21,13 @@ describe('DROPINDEX', () => {
});
testUtils.testWithClient('client.ft.dropIndex', async client => {
await client.ft.create('index', {
field: SchemaFieldTypes.TEXT
});
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.dropIndex('index')
]);
assert.equal(
await client.ft.dropIndex('index'),
'OK'
);
assert.equal(reply, 'OK');
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -6,7 +6,7 @@ export interface FtDropIndexOptions {
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument, options?: FtDropIndexOptions) {
const args = ['FT.DROPINDEX', index];

View File

@@ -1,80 +1,80 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { SchemaFieldTypes } from '.';
import { transformArguments } from './SPELLCHECK';
import SPELLCHECK from './SPELLCHECK';
describe('SPELLCHECK', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(
transformArguments('index', 'query'),
['FT.SPELLCHECK', 'index', 'query']
);
});
it('with DISTANCE', () => {
assert.deepEqual(
transformArguments('index', 'query', { DISTANCE: 2 }),
['FT.SPELLCHECK', 'index', 'query', 'DISTANCE', '2']
);
});
describe('with TERMS', () => {
it('single', () => {
assert.deepEqual(
transformArguments('index', 'query', {
TERMS: {
mode: 'INCLUDE',
dictionary: 'dictionary'
}
}),
['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'dictionary']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments('index', 'query', {
TERMS: [{
mode: 'INCLUDE',
dictionary: 'include'
}, {
mode: 'EXCLUDE',
dictionary: 'exclude'
}]
}),
['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'include', 'TERMS', 'EXCLUDE', 'exclude']
);
});
});
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', 'query', {
DIALECT: 1
}),
['FT.SPELLCHECK', 'index', 'query', 'DIALECT', '1']
);
});
describe('FT.SPELLCHECK', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(
SPELLCHECK.transformArguments('index', 'query'),
['FT.SPELLCHECK', 'index', 'query']
);
});
testUtils.testWithClient('client.ft.spellCheck', async client => {
await Promise.all([
client.ft.create('index', {
field: SchemaFieldTypes.TEXT
}),
client.hSet('key', 'field', 'query')
]);
it('with DISTANCE', () => {
assert.deepEqual(
SPELLCHECK.transformArguments('index', 'query', {
DISTANCE: 2
}),
['FT.SPELLCHECK', 'index', 'query', 'DISTANCE', '2']
);
});
describe('with TERMS', () => {
it('single', () => {
assert.deepEqual(
await client.ft.spellCheck('index', 'quer'),
[{
term: 'quer',
suggestions: [{
score: 1,
suggestion: 'query'
}]
}]
SPELLCHECK.transformArguments('index', 'query', {
TERMS: {
mode: 'INCLUDE',
dictionary: 'dictionary'
}
}),
['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'dictionary']
);
}, GLOBAL.SERVERS.OPEN);
});
it('multiple', () => {
assert.deepEqual(
SPELLCHECK.transformArguments('index', 'query', {
TERMS: [{
mode: 'INCLUDE',
dictionary: 'include'
}, {
mode: 'EXCLUDE',
dictionary: 'exclude'
}]
}),
['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'include', 'TERMS', 'EXCLUDE', 'exclude']
);
});
});
it('with DIALECT', () => {
assert.deepEqual(
SPELLCHECK.transformArguments('index', 'query', {
DIALECT: 1
}),
['FT.SPELLCHECK', 'index', 'query', 'DIALECT', '1']
);
});
});
testUtils.testWithClient('client.ft.spellCheck', async client => {
const [,, reply] = await Promise.all([
client.ft.create('index', {
field: SchemaFieldTypes.TEXT
}),
client.hSet('key', 'field', 'query'),
client.ft.spellCheck('index', 'quer')
]);
assert.deepEqual(reply, [{
term: 'quer',
suggestions: [{
score: 1,
suggestion: 'query'
}]
}]);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,62 +1,69 @@
interface SpellCheckTerms {
mode: 'INCLUDE' | 'EXCLUDE';
dictionary: string;
import { RedisArgument, CommandArguments, Command } from '@redis/client/dist/lib/RESP/types';
export interface Terms {
mode: 'INCLUDE' | 'EXCLUDE';
dictionary: RedisArgument;
}
interface SpellCheckOptions {
DISTANCE?: number;
TERMS?: SpellCheckTerms | Array<SpellCheckTerms>;
DIALECT?: number;
export interface FtSpellCheckOptions {
DISTANCE?: number;
TERMS?: Terms | Array<Terms>;
DIALECT?: number;
}
export function transformArguments(index: string, query: string, options?: SpellCheckOptions): Array<string> {
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument, query: RedisArgument, options?: FtSpellCheckOptions) {
const args = ['FT.SPELLCHECK', index, query];
if (options?.DISTANCE) {
args.push('DISTANCE', options.DISTANCE.toString());
args.push('DISTANCE', options.DISTANCE.toString());
}
if (options?.TERMS) {
if (Array.isArray(options.TERMS)) {
for (const term of options.TERMS) {
pushTerms(args, term);
}
} else {
pushTerms(args, options.TERMS);
if (Array.isArray(options.TERMS)) {
for (const term of options.TERMS) {
pushTerms(args, term);
}
} else {
pushTerms(args, options.TERMS);
}
}
if (options?.DIALECT) {
args.push('DIALECT', options.DIALECT.toString());
args.push('DIALECT', options.DIALECT.toString());
}
return args;
}
function pushTerms(args: Array<string>, { mode, dictionary }: SpellCheckTerms): void {
args.push('TERMS', mode, dictionary);
}
type SpellCheckRawReply = Array<[
_: string,
term: string,
suggestions: Array<[score: string, suggestion: string]>
]>;
type SpellCheckReply = Array<{
term: string,
suggestions: Array<{
score: number,
suggestion: string
}>
}>;
export function transformReply(rawReply: SpellCheckRawReply): SpellCheckReply {
return rawReply.map(([, term, suggestions]) => ({
term,
suggestions: suggestions.map(([score, suggestion]) => ({
score: Number(score),
suggestion
}))
}));
},
// TODO
// type SpellCheckRawReply = Array<[
// _: string,
// term: string,
// suggestions: Array<[score: string, suggestion: string]>
// ]>;
// type SpellCheckReply = Array<{
// term: string,
// suggestions: Array<{
// score: number,
// suggestion: string
// }>
// }>;
// export function transformReply(rawReply: SpellCheckRawReply): SpellCheckReply {
// return rawReply.map(([, term, suggestions]) => ({
// term,
// suggestions: suggestions.map(([score, suggestion]) => ({
// score: Number(score),
// suggestion
// }))
// }));
// }
transformReply: undefined as unknown as () => any
} as const satisfies Command;
function pushTerms(args: CommandArguments, { mode, dictionary }: Terms) {
args.push('TERMS', mode, dictionary);
}

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import SUGADD from './SUGADD';
describe('SUGADD', () => {
describe('FT.SUGADD', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(

View File

@@ -7,7 +7,7 @@ export interface FtSugAddOptions {
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(key: RedisArgument, string: RedisArgument, score: number, options?: FtSugAddOptions) {
const args = ['FT.SUGADD', key, string, score.toString()];

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import SUGDEL from './SUGDEL';
describe('SUGDEL', () => {
describe('FT.SUGDEL', () => {
it('transformArguments', () => {
assert.deepEqual(
SUGDEL.transformArguments('key', 'string'),
@@ -13,7 +13,7 @@ describe('SUGDEL', () => {
testUtils.testWithClient('client.ft.sugDel', async client => {
assert.equal(
await client.ft.sugDel('key', 'string'),
false
0
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -2,7 +2,7 @@ import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(key: RedisArgument, string: RedisArgument) {
return ['FT.SUGDEL', key, string];
},

View File

@@ -1,46 +1,46 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SUGGET';
import SUGGET from './SUGGET';
describe('SUGGET', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(
transformArguments('key', 'prefix'),
['FT.SUGGET', 'key', 'prefix']
);
});
it('with FUZZY', () => {
assert.deepEqual(
transformArguments('key', 'prefix', { FUZZY: true }),
['FT.SUGGET', 'key', 'prefix', 'FUZZY']
);
});
it('with MAX', () => {
assert.deepEqual(
transformArguments('key', 'prefix', { MAX: 10 }),
['FT.SUGGET', 'key', 'prefix', 'MAX', '10']
);
});
describe('FT.SUGGET', () => {
describe('transformArguments', () => {
it('without options', () => {
assert.deepEqual(
SUGGET.transformArguments('key', 'prefix'),
['FT.SUGGET', 'key', 'prefix']
);
});
describe('client.ft.sugGet', () => {
testUtils.testWithClient('null', async client => {
assert.equal(
await client.ft.sugGet('key', 'prefix'),
null
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithClient('with suggestions', async client => {
await client.ft.sugAdd('key', 'string', 1);
assert.deepEqual(
await client.ft.sugGet('key', 'string'),
['string']
);
}, GLOBAL.SERVERS.OPEN);
it('with FUZZY', () => {
assert.deepEqual(
SUGGET.transformArguments('key', 'prefix', { FUZZY: true }),
['FT.SUGGET', 'key', 'prefix', 'FUZZY']
);
});
it('with MAX', () => {
assert.deepEqual(
SUGGET.transformArguments('key', 'prefix', { MAX: 10 }),
['FT.SUGGET', 'key', 'prefix', 'MAX', '10']
);
});
});
describe('client.ft.sugGet', () => {
testUtils.testWithClient('null', async client => {
assert.equal(
await client.ft.sugGet('key', 'prefix'),
null
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithClient('with suggestions', async client => {
const [, reply] = await Promise.all([
client.ft.sugAdd('key', 'string', 1),
client.ft.sugGet('key', 's')
]);
assert.deepEqual(reply, ['string']);
}, GLOBAL.SERVERS.OPEN);
});
});

View File

@@ -1,22 +1,25 @@
export const IS_READ_ONLY = true;
import { ArrayReply, BlobStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
export interface SugGetOptions {
FUZZY?: true;
MAX?: number;
export interface FtSugGetOptions {
FUZZY?: boolean;
MAX?: number;
}
export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array<string> {
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(key: RedisArgument, prefix: RedisArgument, options?: FtSugGetOptions) {
const args = ['FT.SUGGET', key, prefix];
if (options?.FUZZY) {
args.push('FUZZY');
args.push('FUZZY');
}
if (options?.MAX) {
args.push('MAX', options.MAX.toString());
if (options?.MAX !== undefined) {
args.push('MAX', options.MAX.toString());
}
return args;
}
export declare function transformReply(): null | Array<string>;
},
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
} as const satisfies Command;

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import SUGLEN from './SUGLEN';
describe('SUGLEN', () => {
describe('FT.SUGLEN', () => {
it('transformArguments', () => {
assert.deepEqual(
SUGLEN.transformArguments('key'),

View File

@@ -1,24 +1,24 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SYNDUMP';
import { SchemaFieldTypes } from '.';
import SYNDUMP from './SYNDUMP';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('SYNDUMP', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('index'),
['FT.SYNDUMP', 'index']
);
});
describe('FT.SYNDUMP', () => {
it('transformArguments', () => {
assert.deepEqual(
SYNDUMP.transformArguments('index'),
['FT.SYNDUMP', 'index']
);
});
testUtils.testWithClient('client.ft.synDump', async client => {
await client.ft.create('index', {
field: SchemaFieldTypes.TEXT
});
testUtils.testWithClient('client.ft.synDump', async client => {
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.synDump('index')
]);
assert.deepEqual(
await client.ft.synDump('index'),
[]
);
}, GLOBAL.SERVERS.OPEN);
assert.deepEqual(reply, []);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,5 +1,22 @@
export function transformArguments(index: string): Array<string> {
return ['FT.SYNDUMP', index];
}
import { RedisArgument, MapReply, BlobStringReply, ArrayReply, UnwrapReply, Command } from '@redis/client/dist/lib/RESP/types';
export declare function transformReply(): Array<string>;
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument) {
return ['FT.SYNDUMP', index];
},
transformReply: {
2: (reply: UnwrapReply<ArrayReply<BlobStringReply | ArrayReply<BlobStringReply>>>) => {
const result: Record<string, ArrayReply<BlobStringReply>> = {};
let i = 0;
while (i < reply.length) {
const key = (reply[i++] as unknown as UnwrapReply<BlobStringReply>).toString(),
value = reply[i++] as unknown as ArrayReply<BlobStringReply>;
result[key] = value;
}
return result;
},
3: undefined as unknown as () => MapReply<BlobStringReply, ArrayReply<BlobStringReply>>
}
} as const satisfies Command;

View File

@@ -1,40 +1,42 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SYNUPDATE';
import { SchemaFieldTypes } from '.';
import SYNUPDATE from './SYNUPDATE';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('SYNUPDATE', () => {
describe('transformArguments', () => {
it('single term', () => {
assert.deepEqual(
transformArguments('index', 'groupId', 'term'),
['FT.SYNUPDATE', 'index', 'groupId', 'term']
);
});
it('multiple terms', () => {
assert.deepEqual(
transformArguments('index', 'groupId', ['1', '2']),
['FT.SYNUPDATE', 'index', 'groupId', '1', '2']
);
});
it('with SKIPINITIALSCAN', () => {
assert.deepEqual(
transformArguments('index', 'groupId', 'term', { SKIPINITIALSCAN: true }),
['FT.SYNUPDATE', 'index', 'groupId', 'SKIPINITIALSCAN', 'term']
);
});
describe('FT.SYNUPDATE', () => {
describe('transformArguments', () => {
it('single term', () => {
assert.deepEqual(
SYNUPDATE.transformArguments('index', 'groupId', 'term'),
['FT.SYNUPDATE', 'index', 'groupId', 'term']
);
});
testUtils.testWithClient('client.ft.synUpdate', async client => {
await client.ft.create('index', {
field: SchemaFieldTypes.TEXT
});
it('multiple terms', () => {
assert.deepEqual(
SYNUPDATE.transformArguments('index', 'groupId', ['1', '2']),
['FT.SYNUPDATE', 'index', 'groupId', '1', '2']
);
});
assert.equal(
await client.ft.synUpdate('index', 'groupId', 'term'),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
it('with SKIPINITIALSCAN', () => {
assert.deepEqual(
SYNUPDATE.transformArguments('index', 'groupId', 'term', {
SKIPINITIALSCAN: true
}),
['FT.SYNUPDATE', 'index', 'groupId', 'SKIPINITIALSCAN', 'term']
);
});
});
testUtils.testWithClient('client.ft.synUpdate', async client => {
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TEXT
}),
client.ft.synUpdate('index', 'groupId', 'term')
]);
assert.equal(reply, 'OK');
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,23 +1,26 @@
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
interface SynUpdateOptions {
SKIPINITIALSCAN?: true;
export interface FtSynUpdateOptions {
SKIPINITIALSCAN?: boolean;
}
export function transformArguments(
index: string,
groupId: string,
terms: string | Array<string>,
options?: SynUpdateOptions
): RedisCommandArguments {
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments(
index: RedisArgument,
groupId: RedisArgument,
terms: RedisVariadicArgument,
options?: FtSynUpdateOptions
) {
const args = ['FT.SYNUPDATE', index, groupId];
if (options?.SKIPINITIALSCAN) {
args.push('SKIPINITIALSCAN');
args.push('SKIPINITIALSCAN');
}
return pushVariadicArguments(args, terms);
}
export declare function transformReply(): 'OK';
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
} as const satisfies Command;

View File

@@ -1,9 +1,9 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { SchemaFieldTypes } from '.';
import TAGVALS from './TAGVALS';
import { SCHEMA_FIELD_TYPE } from './CREATE';
describe('TAGVALS', () => {
describe('FT.TAGVALS', () => {
it('transformArguments', () => {
assert.deepEqual(
TAGVALS.transformArguments('index', '@field'),
@@ -12,13 +12,13 @@ describe('TAGVALS', () => {
});
testUtils.testWithClient('client.ft.tagVals', async client => {
await client.ft.create('index', {
field: SchemaFieldTypes.TAG
});
const [, reply] = await Promise.all([
client.ft.create('index', {
field: SCHEMA_FIELD_TYPE.TAG
}),
client.ft.tagVals('index', 'field')
]);
assert.deepEqual(
await client.ft.tagVals('index', 'field'),
[]
);
assert.deepEqual(reply, []);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -2,7 +2,7 @@ import { RedisArgument, ArrayReply, SetReply, BlobStringReply, Command } from '@
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
IS_READ_ONLY: true,
transformArguments(index: RedisArgument, fieldName: RedisArgument) {
return ['FT.TAGVALS', index, fieldName];
},

View File

@@ -2,13 +2,13 @@ import _LIST from './_LIST';
// import ALTER from './ALTER';
// import AGGREGATE_WITHCURSOR from './AGGREGATE_WITHCURSOR';
// import AGGREGATE from './AGGREGATE';
// import ALIASADD from './ALIASADD';
// import ALIASDEL from './ALIASDEL';
// import ALIASUPDATE from './ALIASUPDATE';
import ALIASADD from './ALIASADD';
import ALIASDEL from './ALIASDEL';
import ALIASUPDATE from './ALIASUPDATE';
// import CONFIG_GET from './CONFIG_GET';
// import CONFIG_SET from './CONFIG_SET';
import CREATE from './CREATE';
// import CURSOR_DEL from './CURSOR_DEL';
import CURSOR_DEL from './CURSOR_DEL';
// import CURSOR_READ from './CURSOR_READ';
import DICTADD from './DICTADD';
import DICTDEL from './DICTDEL';
@@ -20,16 +20,16 @@ import EXPLAINCLI from './EXPLAINCLI';
// import PROFILESEARCH from './PROFILE_SEARCH';
// import PROFILEAGGREGATE from './PROFILE_AGGREGATE';
// import SEARCH from './SEARCH';
// import SPELLCHECK from './SPELLCHECK';
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 from './SUGGET';
import SUGGET from './SUGGET';
import SUGLEN from './SUGLEN';
// import SYNDUMP from './SYNDUMP';
// import SYNUPDATE from './SYNUPDATE';
import SYNDUMP from './SYNDUMP';
import SYNUPDATE from './SYNUPDATE';
import TAGVALS from './TAGVALS';
// import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
import { pushOptionalVariadicArgument, pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
@@ -45,20 +45,20 @@ export default {
// aggregateWithCursor: AGGREGATE_WITHCURSOR,
// AGGREGATE,
// aggregate: AGGREGATE,
// ALIASADD,
// aliasAdd: ALIASADD,
// ALIASDEL,
// aliasDel: ALIASDEL,
// ALIASUPDATE,
// aliasUpdate: ALIASUPDATE,
ALIASADD,
aliasAdd: ALIASADD,
ALIASDEL,
aliasDel: ALIASDEL,
ALIASUPDATE,
aliasUpdate: ALIASUPDATE,
// CONFIG_GET,
// configGet: CONFIG_GET,
// CONFIG_SET,
// configSet: CONFIG_SET,
CREATE,
create: CREATE,
// CURSOR_DEL,
// cursorDel: CURSOR_DEL,
CURSOR_DEL,
cursorDel: CURSOR_DEL,
// CURSOR_READ,
// cursorRead: CURSOR_READ,
DICTADD,
@@ -81,8 +81,8 @@ export default {
// profileAggregate: PROFILEAGGREGATE,
// SEARCH,
// search: SEARCH,
// SPELLCHECK,
// spellCheck: SPELLCHECK,
SPELLCHECK,
spellCheck: SPELLCHECK,
SUGADD,
sugAdd: SUGADD,
SUGDEL,
@@ -93,14 +93,14 @@ export default {
// sugGetWithScoresWithPayloads: SUGGET_WITHSCORES_WITHPAYLOADS,
// SUGGET_WITHSCORES,
// sugGetWithScores: SUGGET_WITHSCORES,
// SUGGET,
// sugGet: SUGGET,
SUGGET,
sugGet: SUGGET,
SUGLEN,
sugLen: SUGLEN,
// SYNDUMP,
// synDump: SYNDUMP,
// SYNUPDATE,
// synUpdate: SYNUPDATE,
SYNDUMP,
synDump: SYNDUMP,
SYNUPDATE,
synUpdate: SYNUPDATE,
TAGVALS,
tagVals: TAGVALS
};

View File

@@ -5,7 +5,8 @@
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist/"
"dist/",
"!dist/tsconfig.tsbuildinfo"
],
"scripts": {
"test": "nyc -r text-summary -r lcov mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'"