Skip to content

Commit 165ecd0

Browse files
authored
fix(client): require XADD TRIM strategy to match the command grammar (#3418)
* fix(client): require XADD TRIM strategy to match the command grammar * fix(client): always emit XADD TRIM strategy and align remaining specs
1 parent 7809d28 commit 165ecd0

4 files changed

Lines changed: 42 additions & 15 deletions

File tree

packages/client/lib/commands/XADD.spec.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ describe('XADD', () => {
3131
field: 'value'
3232
}, {
3333
TRIM: {
34-
threshold: 1000
34+
strategy: 'MINID',
35+
threshold: 5
3536
}
3637
}),
37-
['XADD', 'key', '1000', '*', 'field', 'value']
38+
['XADD', 'key', 'MINID', '5', '*', 'field', 'value']
3839
);
3940
});
4041

@@ -58,11 +59,12 @@ describe('XADD', () => {
5859
field: 'value'
5960
}, {
6061
TRIM: {
62+
strategy: 'MAXLEN',
6163
strategyModifier: '=',
6264
threshold: 1000
6365
}
6466
}),
65-
['XADD', 'key', '=', '1000', '*', 'field', 'value']
67+
['XADD', 'key', 'MAXLEN', '=', '1000', '*', 'field', 'value']
6668
);
6769
});
6870

@@ -72,11 +74,12 @@ describe('XADD', () => {
7274
field: 'value'
7375
}, {
7476
TRIM: {
77+
strategy: 'MAXLEN',
7578
threshold: 1000,
7679
limit: 1
7780
}
7881
}),
79-
['XADD', 'key', '1000', 'LIMIT', '1', '*', 'field', 'value']
82+
['XADD', 'key', 'MAXLEN', '1000', 'LIMIT', '1', '*', 'field', 'value']
8083
);
8184
});
8285

@@ -86,11 +89,12 @@ describe('XADD', () => {
8689
field: 'value'
8790
}, {
8891
TRIM: {
92+
strategy: 'MAXLEN',
8993
threshold: 1000,
9094
limit: 0
9195
}
9296
}),
93-
['XADD', 'key', '1000', 'LIMIT', '0', '*', 'field', 'value']
97+
['XADD', 'key', 'MAXLEN', '1000', 'LIMIT', '0', '*', 'field', 'value']
9498
);
9599
});
96100

@@ -100,11 +104,12 @@ describe('XADD', () => {
100104
field: 'value'
101105
}, {
102106
TRIM: {
107+
strategy: 'MAXLEN',
103108
threshold: 1000,
104109
policy: STREAM_DELETION_POLICY.DELREF
105110
}
106111
}),
107-
['XADD', 'key', '1000', 'DELREF', '*', 'field', 'value']
112+
['XADD', 'key', 'MAXLEN', '1000', 'DELREF', '*', 'field', 'value']
108113
);
109114
});
110115

packages/client/lib/commands/XADD.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ export interface XAddOptions {
3232
iid: RedisArgument;
3333
};
3434
TRIM?: {
35-
strategy?: 'MAXLEN' | 'MINID';
35+
/**
36+
* Required by the XADD grammar: without MAXLEN or MINID the server parses
37+
* the threshold as the entry ID instead of trimming.
38+
*/
39+
strategy: 'MAXLEN' | 'MINID';
3640
strategyModifier?: '=' | '~';
3741
threshold: number;
3842
limit?: number;
@@ -79,9 +83,7 @@ export function parseXAddArguments(
7983

8084
// Trimming options
8185
if (options?.TRIM) {
82-
if (options.TRIM.strategy) {
83-
parser.push(options.TRIM.strategy);
84-
}
86+
parser.push(options.TRIM.strategy);
8587

8688
if (options.TRIM.strategyModifier) {
8789
parser.push(options.TRIM.strategyModifier);

packages/client/lib/commands/XADD_NOMKSTREAM.spec.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ describe('XADD NOMKSTREAM', () => {
3333
field: 'value'
3434
}, {
3535
TRIM: {
36-
threshold: 1000
36+
strategy: 'MINID',
37+
threshold: 5
3738
}
3839
}),
39-
['XADD', 'key', 'NOMKSTREAM', '1000', '*', 'field', 'value']
40+
['XADD', 'key', 'NOMKSTREAM', 'MINID', '5', '*', 'field', 'value']
4041
);
4142
});
4243

@@ -60,11 +61,12 @@ describe('XADD NOMKSTREAM', () => {
6061
field: 'value'
6162
}, {
6263
TRIM: {
64+
strategy: 'MAXLEN',
6365
strategyModifier: '=',
6466
threshold: 1000
6567
}
6668
}),
67-
['XADD', 'key', 'NOMKSTREAM', '=', '1000', '*', 'field', 'value']
69+
['XADD', 'key', 'NOMKSTREAM', 'MAXLEN', '=', '1000', '*', 'field', 'value']
6870
);
6971
});
7072

@@ -74,11 +76,12 @@ describe('XADD NOMKSTREAM', () => {
7476
field: 'value'
7577
}, {
7678
TRIM: {
79+
strategy: 'MAXLEN',
7780
threshold: 1000,
7881
limit: 1
7982
}
8083
}),
81-
['XADD', 'key', 'NOMKSTREAM', '1000', 'LIMIT', '1', '*', 'field', 'value']
84+
['XADD', 'key', 'NOMKSTREAM', 'MAXLEN', '1000', 'LIMIT', '1', '*', 'field', 'value']
8285
);
8386
});
8487

@@ -88,11 +91,12 @@ describe('XADD NOMKSTREAM', () => {
8891
field: 'value'
8992
}, {
9093
TRIM: {
94+
strategy: 'MAXLEN',
9195
threshold: 1000,
9296
policy: STREAM_DELETION_POLICY.DELREF
9397
}
9498
}),
95-
['XADD', 'key', 'NOMKSTREAM', '1000', 'DELREF', '*', 'field', 'value']
99+
['XADD', 'key', 'NOMKSTREAM', 'MAXLEN', '1000', 'DELREF', '*', 'field', 'value']
96100
);
97101
});
98102

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Compile-time regression: XADD's TRIM.strategy must be required. The official
3+
* grammar makes MAXLEN|MINID mandatory inside the trim block; with the strategy
4+
* omitted, parseXAddArguments emitted a bare threshold which the server parses
5+
* as the entry ID instead of a trim instruction.
6+
*
7+
* Lives outside `lib/` so it is not picked up by the production build /
8+
* typedoc. Checked with `npm run test:types -w @redis/client`.
9+
*/
10+
import { XAddOptions } from '../lib/commands/XADD';
11+
12+
export function xaddTrimRequiresStrategy(): void {
13+
// @ts-expect-error TRIM.strategy is required alongside threshold
14+
const invalidTrim: NonNullable<XAddOptions['TRIM']> = { threshold: 1000 };
15+
console.log(invalidTrim);
16+
}

0 commit comments

Comments
 (0)