Skip to content

Commit 7ead8e4

Browse files
committed
fix TS.M[REV]RANGE[_WITHLABELS|_SELECTED_LABELS] & TS.MGET[_WITHLABELS|_SELECTED_LABELS]
1 parent fcdb1c0 commit 7ead8e4

34 files changed

+1553
-535
lines changed

packages/time-series/lib/commands/MGET.spec.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,17 @@ describe('TS.MGET', () => {
2929
client.ts.mGet('label=value')
3030
]);
3131

32-
const obj = Object.assign(Object.create(null), {
33-
'key': {
34-
sample: {
35-
timestamp: 0,
36-
value: 0
32+
assert.deepStrictEqual(reply, Object.create(null, {
33+
key: {
34+
configurable: true,
35+
enumerable: true,
36+
value: {
37+
sample: {
38+
timestamp: 0,
39+
value: 0
40+
}
3741
}
3842
}
39-
});
40-
41-
assert.deepStrictEqual(reply, obj);
43+
}));
4244
}, GLOBAL.SERVERS.OPEN);
4345
});
Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { CommandArguments, Command, BlobStringReply, ArrayReply, UnwrapReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/dist/lib/RESP/types';
1+
import { CommandArguments, Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/dist/lib/RESP/types';
22
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
3-
import { RawLabels2, RawLabels3, resp2MapToValue, resp3MapToValue, SampleRawReply, transformSampleReply } from '.';
3+
import { resp2MapToValue, resp3MapToValue, SampleRawReply, transformSampleReply } from '.';
44

55
export interface TsMGetOptions {
66
LATEST?: boolean;
@@ -19,45 +19,21 @@ export function pushFilterArgument(args: CommandArguments, filter: RedisVariadic
1919
return pushVariadicArguments(args, filter);
2020
}
2121

22-
export type MGetRawReplyValue2 = TuplesReply<[
23-
key: BlobStringReply,
24-
labels: RawLabels2,
25-
sample: Resp2Reply<SampleRawReply>
26-
]>
27-
28-
export type MGetRawReply2 = ArrayReply<MGetRawReplyValue2>;
29-
30-
export type MGetRawReplyValue3 = TuplesReply<[
31-
labels: RawLabels3,
32-
sample: SampleRawReply
33-
]>;
22+
export type MGetRawReply2 = ArrayReply<
23+
TuplesReply<[
24+
key: BlobStringReply,
25+
labels: never,
26+
sample: Resp2Reply<SampleRawReply>
27+
]>
28+
>;
3429

3530
export type MGetRawReply3 = MapReply<
3631
BlobStringReply,
37-
MGetRawReplyValue3
38-
>
39-
40-
export interface MGetReply2 {
41-
key: BlobStringReply;
42-
sample: ReturnType<typeof transformSampleReply[2]>;
43-
}
44-
45-
export interface MGetReply3 {
46-
key: BlobStringReply | string
47-
sample: ReturnType<typeof transformSampleReply[3]>;
48-
}
49-
50-
export function parseResp3Mget(value: UnwrapReply<MGetRawReplyValue3>) {
51-
return {
52-
sample: transformSampleReply[3](value[1])
53-
};
54-
}
55-
56-
export function parseResp2Mget(value: UnwrapReply<MGetRawReplyValue2>) {
57-
return {
58-
sample: transformSampleReply[2](value[2])
59-
};
60-
}
32+
TuplesReply<[
33+
labels: never,
34+
sample: SampleRawReply
35+
]>
36+
>;
6137

6238
export default {
6339
FIRST_KEY_INDEX: undefined,
@@ -67,11 +43,19 @@ export default {
6743
return pushFilterArgument(args, filter);
6844
},
6945
transformReply: {
70-
2(reply: UnwrapReply<MGetRawReply2>, preserve?: any, typeMapping?: TypeMapping) {
71-
return resp2MapToValue(reply, parseResp2Mget, typeMapping);
46+
2(reply: MGetRawReply2, _, typeMapping?: TypeMapping) {
47+
return resp2MapToValue(reply, ([,, sample]) => {
48+
return {
49+
sample: transformSampleReply[2](sample)
50+
};
51+
}, typeMapping);
7252
},
73-
3(reply: UnwrapReply<MGetRawReply3>) {
74-
return resp3MapToValue(reply, parseResp3Mget)
53+
3(reply: MGetRawReply3) {
54+
return resp3MapToValue(reply, ([, sample]) => {
55+
return {
56+
sample: transformSampleReply[3](sample)
57+
};
58+
});
7559
}
7660
}
7761
} as const satisfies Command;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import MGET_SELECTED_LABELS from './MGET_SELECTED_LABELS';
4+
5+
describe('TS.MGET_SELECTED_LABELS', () => {
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
MGET_SELECTED_LABELS.transformArguments('label=value', 'label'),
9+
['TS.MGET', 'SELECTED_LABELS', 'label', 'FILTER', 'label=value']
10+
);
11+
});
12+
13+
testUtils.testWithClient('client.ts.mGetSelectedLabels', async client => {
14+
const [, reply] = await Promise.all([
15+
client.ts.add('key', 0, 0, {
16+
LABELS: { label: 'value' }
17+
}),
18+
client.ts.mGetSelectedLabels('label=value', ['label', 'NX'])
19+
]);
20+
21+
assert.deepStrictEqual(reply, Object.create(null, {
22+
key: {
23+
configurable: true,
24+
enumerable: true,
25+
value: {
26+
labels: Object.create(null, {
27+
label: {
28+
configurable: true,
29+
enumerable: true,
30+
value: 'value'
31+
},
32+
NX: {
33+
configurable: true,
34+
enumerable: true,
35+
value: null
36+
}
37+
}),
38+
sample: {
39+
timestamp: 0,
40+
value: 0
41+
}
42+
}
43+
}
44+
}));
45+
}, GLOBAL.SERVERS.OPEN);
46+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Command, BlobStringReply, NullReply } from '@redis/client/dist/lib/RESP/types';
2+
import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
3+
import { TsMGetOptions, pushLatestArgument, pushFilterArgument } from './MGET';
4+
import { pushSelectedLabelsArguments } from '.';
5+
import { createTransformMGetLabelsReply } from './MGET_WITHLABELS';
6+
7+
export default {
8+
FIRST_KEY_INDEX: undefined,
9+
IS_READ_ONLY: true,
10+
transformArguments(filter: RedisVariadicArgument, selectedLabels: RedisVariadicArgument, options?: TsMGetOptions) {
11+
let args = pushLatestArgument(['TS.MGET'], options?.LATEST);
12+
args = pushSelectedLabelsArguments(args, selectedLabels);
13+
return pushFilterArgument(args, filter);
14+
},
15+
transformReply: createTransformMGetLabelsReply<BlobStringReply | NullReply>(),
16+
} as const satisfies Command;

packages/time-series/lib/commands/MGET_WITHLABELS.spec.ts

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,11 @@ import testUtils, { GLOBAL } from '../test-utils';
33
import MGET_WITHLABELS from './MGET_WITHLABELS';
44

55
describe('TS.MGET_WITHLABELS', () => {
6-
describe('transformArguments', () => {
7-
it('without options', () => {
8-
assert.deepEqual(
9-
MGET_WITHLABELS.transformArguments('label=value'),
10-
['TS.MGET', 'WITHLABELS', 'FILTER', 'label=value']
11-
);
12-
});
13-
14-
it('with SELECTED_LABELS', () => {
15-
assert.deepEqual(
16-
MGET_WITHLABELS.transformArguments('label=value', {
17-
SELECTED_LABELS: 'label'
18-
}),
19-
['TS.MGET', 'SELECTED_LABELS', 'label', 'FILTER', 'label=value']
20-
);
21-
});
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
MGET_WITHLABELS.transformArguments('label=value'),
9+
['TS.MGET', 'WITHLABELS', 'FILTER', 'label=value']
10+
);
2211
});
2312

2413
testUtils.testWithClient('client.ts.mGetWithLabels', async client => {
@@ -28,17 +17,25 @@ describe('TS.MGET_WITHLABELS', () => {
2817
}),
2918
client.ts.mGetWithLabels('label=value')
3019
]);
31-
32-
const obj = Object.assign(Object.create(null), {
33-
'key': {
34-
labels: { label: 'value' },
35-
sample: {
36-
timestamp: 0,
37-
value: 0
20+
21+
assert.deepStrictEqual(reply, Object.create(null, {
22+
key: {
23+
configurable: true,
24+
enumerable: true,
25+
value: {
26+
labels: Object.create(null, {
27+
label: {
28+
configurable: true,
29+
enumerable: true,
30+
value: 'value'
31+
}
32+
}),
33+
sample: {
34+
timestamp: 0,
35+
value: 0
36+
}
3837
}
3938
}
40-
});
41-
42-
assert.deepStrictEqual(reply, obj);
39+
}));
4340
}, GLOBAL.SERVERS.OPEN);
4441
});
Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,61 @@
1-
import { Command, TypeMapping, UnwrapReply } from '@redis/client/dist/lib/RESP/types';
1+
import { Command, BlobStringReply, ArrayReply, Resp2Reply, MapReply, TuplesReply, TypeMapping } from '@redis/client/dist/lib/RESP/types';
22
import { RedisVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
3-
import { TsMGetOptions, pushLatestArgument, pushFilterArgument, MGetReply2, MGetRawReply2, MGetReply3, MGetRawReplyValue3, MGetRawReply3, parseResp3Mget, parseResp2Mget, MGetRawReplyValue2 } from './MGET';
4-
import { Labels, pushWithLabelsArgument, resp2MapToValue, resp3MapToValue, transformLablesReply2, transformLablesReply3 } from '.';
3+
import { TsMGetOptions, pushLatestArgument, pushFilterArgument } from './MGET';
4+
import { RawLabelValue, resp2MapToValue, resp3MapToValue, SampleRawReply, transformRESP2Labels, transformSampleReply } from '.';
55

66
export interface TsMGetWithLabelsOptions extends TsMGetOptions {
77
SELECTED_LABELS?: RedisVariadicArgument;
88
}
99

10-
export interface MGetWithLabelsReply2 extends MGetReply2 {
11-
labels: Labels;
12-
};
13-
14-
export interface MGetWithLabelsReply3 extends MGetReply3 {
15-
labels: Labels;
16-
};
17-
18-
function parseResp2MgetWithLabels(
19-
value: UnwrapReply<MGetRawReplyValue2>,
20-
): MGetWithLabelsReply3 {
21-
const ret = parseResp2Mget(value) as unknown as MGetWithLabelsReply3;
22-
ret.labels = transformLablesReply2(value[1]);
23-
24-
return ret;
25-
}
26-
27-
function parseResp3MgetWithLabels(value: UnwrapReply<MGetRawReplyValue3>): MGetWithLabelsReply3 {
28-
const ret = parseResp3Mget(value) as MGetWithLabelsReply3;
29-
ret.labels = transformLablesReply3(value[0]);
30-
31-
return ret;
10+
export type MGetLabelsRawReply2<T extends RawLabelValue> = ArrayReply<
11+
TuplesReply<[
12+
key: BlobStringReply,
13+
labels: ArrayReply<
14+
TuplesReply<[
15+
label: BlobStringReply,
16+
value: T
17+
]>
18+
>,
19+
sample: Resp2Reply<SampleRawReply>
20+
]>
21+
>;
22+
23+
export type MGetLabelsRawReply3<T extends RawLabelValue> = MapReply<
24+
BlobStringReply,
25+
TuplesReply<[
26+
labels: MapReply<BlobStringReply, T>,
27+
sample: SampleRawReply
28+
]>
29+
>;
30+
31+
export function createTransformMGetLabelsReply<T extends RawLabelValue>() {
32+
return {
33+
2(reply: MGetLabelsRawReply2<T>, _, typeMapping?: TypeMapping) {
34+
return resp2MapToValue(reply, ([, labels, sample]) => {
35+
return {
36+
labels: transformRESP2Labels(labels),
37+
sample: transformSampleReply[2](sample)
38+
};
39+
}, typeMapping);
40+
},
41+
3(reply: MGetLabelsRawReply3<T>) {
42+
return resp3MapToValue(reply, ([labels, sample]) => {
43+
return {
44+
labels,
45+
sample: transformSampleReply[3](sample)
46+
};
47+
});
48+
}
49+
} satisfies Command['transformReply'];
3250
}
3351

3452
export default {
3553
FIRST_KEY_INDEX: undefined,
3654
IS_READ_ONLY: true,
37-
transformArguments(filter: RedisVariadicArgument, options?: TsMGetWithLabelsOptions) {
38-
let args = pushLatestArgument(['TS.MGET'], options?.LATEST);
39-
args = pushWithLabelsArgument(args, options?.SELECTED_LABELS);
55+
transformArguments(filter: RedisVariadicArgument, options?: TsMGetOptions) {
56+
const args = pushLatestArgument(['TS.MGET'], options?.LATEST);
57+
args.push('WITHLABELS');
4058
return pushFilterArgument(args, filter);
4159
},
42-
transformReply: {
43-
2(reply: UnwrapReply<MGetRawReply2>, preserve?: any, typeMapping?: TypeMapping) {
44-
return resp2MapToValue(reply, parseResp2MgetWithLabels, typeMapping);
45-
},
46-
3(reply: UnwrapReply<MGetRawReply3>) {
47-
return resp3MapToValue(reply, parseResp3MgetWithLabels);
48-
}
49-
},
60+
transformReply: createTransformMGetLabelsReply<BlobStringReply>(),
5061
} as const satisfies Command;

0 commit comments

Comments
 (0)