Skip to content

Commit 0337343

Browse files
committed
adding "type mapping" to transformReply
enables type mapping of "maps" in resp2 responses that are "fake maps"/mapes in resp3. also enables user configuration of fake maps in resp3 responses (stream message fields).
1 parent 9ac2ee8 commit 0337343

23 files changed

+307
-138
lines changed

packages/client/lib/RESP/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ export interface BlobStringReply<
7777
T,
7878
Buffer,
7979
string | Buffer
80-
> {}
80+
> {
81+
toString(): string
82+
}
8183

8284
export interface VerbatimStringReply<
8385
T extends string = string
@@ -216,7 +218,7 @@ export type ReplyWithTypeMapping<
216218
)
217219
);
218220

219-
export type TransformReply = (this: void, reply: any, preserve?: any) => any; // TODO;
221+
export type TransformReply = (this: void, reply: any, preserve?: any, typeMapping?: TypeMapping) => any; // TODO;
220222

221223
export type RedisArgument = string | Buffer;
222224

packages/client/lib/client/index.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,12 @@ export default class RedisClient<
153153
const transformReply = getTransformReply(command, resp);
154154
return async function (this: ProxyClient, ...args: Array<unknown>) {
155155
const redisArgs = command.transformArguments(...args);
156+
const typeMapping = this._commandOptions?.typeMapping;
157+
156158
const reply = await this.sendCommand(redisArgs, this._commandOptions);
159+
157160
return transformReply ?
158-
transformReply(reply, redisArgs.preserve) :
161+
transformReply(reply, redisArgs.preserve, typeMapping) :
159162
reply;
160163
};
161164
}
@@ -164,9 +167,12 @@ export default class RedisClient<
164167
const transformReply = getTransformReply(command, resp);
165168
return async function (this: NamespaceProxyClient, ...args: Array<unknown>) {
166169
const redisArgs = command.transformArguments(...args);
170+
const typeMapping = this._self._commandOptions?.typeMapping
171+
167172
const reply = await this._self.sendCommand(redisArgs, this._self._commandOptions);
173+
168174
return transformReply ?
169-
transformReply(reply, redisArgs.preserve) :
175+
transformReply(reply, redisArgs.preserve, typeMapping) :
170176
reply;
171177
};
172178
}
@@ -176,13 +182,16 @@ export default class RedisClient<
176182
transformReply = getTransformReply(fn, resp);
177183
return async function (this: NamespaceProxyClient, ...args: Array<unknown>) {
178184
const fnArgs = fn.transformArguments(...args);
185+
const typeMapping = this._self._commandOptions?.typeMapping;
186+
179187
const reply = await this._self.sendCommand(
180188
prefix.concat(fnArgs),
181189
this._self._commandOptions
182190
);
183-
return transformReply ?
184-
transformReply(reply, fnArgs.preserve) :
185-
reply;
191+
192+
return transformReply ?
193+
transformReply(reply, fnArgs.preserve, typeMapping) :
194+
reply;
186195
};
187196
}
188197

@@ -192,9 +201,12 @@ export default class RedisClient<
192201
return async function (this: ProxyClient, ...args: Array<unknown>) {
193202
const scriptArgs = script.transformArguments(...args);
194203
const redisArgs = prefix.concat(scriptArgs);
204+
const typeMapping = this._commandOptions?.typeMapping;
205+
195206
const reply = await this.executeScript(script, redisArgs, this._commandOptions);
207+
196208
return transformReply ?
197-
transformReply(reply, scriptArgs.preserve) :
209+
transformReply(reply, scriptArgs.preserve, typeMapping) :
198210
reply;
199211
};
200212
}
@@ -870,7 +882,8 @@ export default class RedisClient<
870882
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
871883
return new ((this as any).Multi as Multi)(
872884
this._executeMulti.bind(this),
873-
this._executePipeline.bind(this)
885+
this._executePipeline.bind(this),
886+
this._commandOptions?.typeMapping
874887
);
875888
}
876889

packages/client/lib/client/multi-command.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,14 @@ export default class RedisClientMultiCommand<REPLIES = []> {
152152
readonly #multi = new RedisMultiCommand();
153153
readonly #executeMulti: ExecuteMulti;
154154
readonly #executePipeline: ExecuteMulti;
155+
readonly #typeMapping?: TypeMapping;
156+
155157
#selectedDB?: number;
156158

157-
constructor(executeMulti: ExecuteMulti, executePipeline: ExecuteMulti) {
159+
constructor(executeMulti: ExecuteMulti, executePipeline: ExecuteMulti, typeMapping?: TypeMapping) {
158160
this.#executeMulti = executeMulti;
159161
this.#executePipeline = executePipeline;
162+
this.#typeMapping = typeMapping;
160163
}
161164

162165
SELECT(db: number, transformReply?: TransformReply): this {
@@ -176,7 +179,8 @@ export default class RedisClientMultiCommand<REPLIES = []> {
176179
if (execAsPipeline) return this.execAsPipeline<T>();
177180

178181
return this.#multi.transformReplies(
179-
await this.#executeMulti(this.#multi.queue, this.#selectedDB)
182+
await this.#executeMulti(this.#multi.queue, this.#selectedDB),
183+
this.#typeMapping
180184
) as MultiReplyType<T, REPLIES>;
181185
}
182186

@@ -190,7 +194,8 @@ export default class RedisClientMultiCommand<REPLIES = []> {
190194
if (this.#multi.queue.length === 0) return [] as MultiReplyType<T, REPLIES>;
191195

192196
return this.#multi.transformReplies(
193-
await this.#executePipeline(this.#multi.queue, this.#selectedDB)
197+
await this.#executePipeline(this.#multi.queue, this.#selectedDB),
198+
this.#typeMapping
194199
) as MultiReplyType<T, REPLIES>;
195200
}
196201

packages/client/lib/client/pool.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ export class RedisClientPool<
6666
const transformReply = getTransformReply(command, resp);
6767
return async function (this: ProxyPool, ...args: Array<unknown>) {
6868
const redisArgs = command.transformArguments(...args);
69+
const typeMapping = this._commandOptions?.typeMapping;
70+
6971
const reply = await this.sendCommand(redisArgs, this._commandOptions);
72+
7073
return transformReply ?
71-
transformReply(reply, redisArgs.preserve) :
74+
transformReply(reply, redisArgs.preserve, typeMapping) :
7275
reply;
7376
};
7477
}
@@ -77,9 +80,12 @@ export class RedisClientPool<
7780
const transformReply = getTransformReply(command, resp);
7881
return async function (this: NamespaceProxyPool, ...args: Array<unknown>) {
7982
const redisArgs = command.transformArguments(...args);
83+
const typeMapping = this._self._commandOptions?.typeMapping;
84+
8085
const reply = await this._self.sendCommand(redisArgs, this._self._commandOptions);
86+
8187
return transformReply ?
82-
transformReply(reply, redisArgs.preserve) :
88+
transformReply(reply, redisArgs.preserve, typeMapping) :
8389
reply;
8490
};
8591
}
@@ -89,12 +95,15 @@ export class RedisClientPool<
8995
transformReply = getTransformReply(fn, resp);
9096
return async function (this: NamespaceProxyPool, ...args: Array<unknown>) {
9197
const fnArgs = fn.transformArguments(...args);
98+
const typeMapping = this._self._commandOptions?.typeMapping;
99+
92100
const reply = await this._self.sendCommand(
93101
prefix.concat(fnArgs),
94102
this._self._commandOptions
95103
);
104+
96105
return transformReply ?
97-
transformReply(reply, fnArgs.preserve) :
106+
transformReply(reply, fnArgs.preserve, typeMapping) :
98107
reply;
99108
};
100109
}
@@ -105,9 +114,12 @@ export class RedisClientPool<
105114
return async function (this: ProxyPool, ...args: Array<unknown>) {
106115
const scriptArgs = script.transformArguments(...args);
107116
const redisArgs = prefix.concat(scriptArgs);
117+
const typeMapping = this._commandOptions?.typeMapping;
118+
108119
const reply = await this.executeScript(script, redisArgs, this._commandOptions);
120+
109121
return transformReply ?
110-
transformReply(reply, scriptArgs.preserve) :
122+
transformReply(reply, scriptArgs.preserve, typeMapping) :
111123
reply;
112124
};
113125
}
@@ -426,7 +438,8 @@ export class RedisClientPool<
426438
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
427439
return new ((this as any).Multi as Multi)(
428440
(commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)),
429-
commands => this.execute(client => client._executePipeline(commands))
441+
commands => this.execute(client => client._executePipeline(commands)),
442+
this._commandOptions?.typeMapping
430443
);
431444
}
432445

packages/client/lib/cluster/index.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ export default class RedisCluster<
170170
const transformReply = getTransformReply(command, resp);
171171
return async function (this: ProxyCluster, ...args: Array<unknown>) {
172172
const redisArgs = command.transformArguments(...args);
173+
const typeMapping = this._commandOptions?.typeMapping;
174+
173175
const firstKey = RedisCluster.extractFirstKey(
174176
command,
175177
args,
@@ -185,7 +187,7 @@ export default class RedisCluster<
185187
);
186188

187189
return transformReply ?
188-
transformReply(reply, redisArgs.preserve) :
190+
transformReply(reply, redisArgs.preserve, typeMapping) :
189191
reply;
190192
};
191193
}
@@ -194,6 +196,8 @@ export default class RedisCluster<
194196
const transformReply = getTransformReply(command, resp);
195197
return async function (this: NamespaceProxyCluster, ...args: Array<unknown>) {
196198
const redisArgs = command.transformArguments(...args);
199+
const typeMapping = this._self._commandOptions?.typeMapping;
200+
197201
const firstKey = RedisCluster.extractFirstKey(
198202
command,
199203
args,
@@ -209,7 +213,7 @@ export default class RedisCluster<
209213
);
210214

211215
return transformReply ?
212-
transformReply(reply, redisArgs.preserve) :
216+
transformReply(reply, redisArgs.preserve, typeMapping) :
213217
reply;
214218
};
215219
}
@@ -219,12 +223,14 @@ export default class RedisCluster<
219223
transformReply = getTransformReply(fn, resp);
220224
return async function (this: NamespaceProxyCluster, ...args: Array<unknown>) {
221225
const fnArgs = fn.transformArguments(...args);
226+
const redisArgs = prefix.concat(fnArgs);
227+
const typeMapping = this._self._commandOptions?.typeMapping;
228+
222229
const firstKey = RedisCluster.extractFirstKey(
223230
fn,
224231
args,
225232
fnArgs
226233
);
227-
const redisArgs = prefix.concat(fnArgs);
228234

229235
const reply = await this._self.sendCommand(
230236
firstKey,
@@ -235,7 +241,7 @@ export default class RedisCluster<
235241
);
236242

237243
return transformReply ?
238-
transformReply(reply, fnArgs.preserve) :
244+
transformReply(reply, fnArgs.preserve, typeMapping) :
239245
reply;
240246
};
241247
}
@@ -245,12 +251,14 @@ export default class RedisCluster<
245251
transformReply = getTransformReply(script, resp);
246252
return async function (this: ProxyCluster, ...args: Array<unknown>) {
247253
const scriptArgs = script.transformArguments(...args);
254+
const redisArgs = prefix.concat(scriptArgs);
255+
const typeMapping = this._commandOptions?.typeMapping;
256+
248257
const firstKey = RedisCluster.extractFirstKey(
249258
script,
250259
args,
251260
scriptArgs
252261
);
253-
const redisArgs = prefix.concat(scriptArgs);
254262

255263
const reply = await this.executeScript(
256264
script,
@@ -262,7 +270,7 @@ export default class RedisCluster<
262270
);
263271

264272
return transformReply ?
265-
transformReply(reply, scriptArgs.preserve) :
273+
transformReply(reply, scriptArgs.preserve, typeMapping) :
266274
reply;
267275
};
268276
}
@@ -520,7 +528,8 @@ export default class RedisCluster<
520528
const client = await this._self.#slots.getClient(firstKey, isReadonly);
521529
return client._executePipeline(commands);
522530
},
523-
routing
531+
routing,
532+
this._commandOptions?.typeMapping
524533
);
525534
}
526535

packages/client/lib/cluster/multi-command.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,18 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
191191
readonly #executePipeline: ClusterMultiExecute;
192192
#firstKey: RedisArgument | undefined;
193193
#isReadonly: boolean | undefined = true;
194+
readonly #typeMapping?: TypeMapping;
194195

195196
constructor(
196197
executeMulti: ClusterMultiExecute,
197198
executePipeline: ClusterMultiExecute,
198-
routing: RedisArgument | undefined
199+
routing: RedisArgument | undefined,
200+
typeMapping?: TypeMapping
199201
) {
200202
this.#executeMulti = executeMulti;
201203
this.#executePipeline = executePipeline;
202204
this.#firstKey = routing;
205+
this.#typeMapping = typeMapping;
203206
}
204207

205208
#setState(
@@ -229,7 +232,8 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
229232
this.#firstKey,
230233
this.#isReadonly,
231234
this.#multi.queue
232-
)
235+
),
236+
this.#typeMapping
233237
) as MultiReplyType<T, REPLIES>;
234238
}
235239

@@ -247,7 +251,8 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
247251
this.#firstKey,
248252
this.#isReadonly,
249253
this.#multi.queue
250-
)
254+
),
255+
this.#typeMapping
251256
) as MultiReplyType<T, REPLIES>;
252257
}
253258

packages/client/lib/commands/XAUTOCLAIM.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RedisArgument, TuplesReply, BlobStringReply, ArrayReply, NullReply, UnwrapReply, Command } from '../RESP/types';
1+
import { RedisArgument, TuplesReply, BlobStringReply, ArrayReply, NullReply, UnwrapReply, Command, TypeMapping } from '../RESP/types';
22
import { StreamMessageRawReply, transformStreamMessageNullReply } from './generic-transformers';
33

44
export interface XAutoClaimOptions {
@@ -37,10 +37,10 @@ export default {
3737

3838
return args;
3939
},
40-
transformReply(reply: UnwrapReply<XAutoClaimRawReply>) {
40+
transformReply(reply: UnwrapReply<XAutoClaimRawReply>, preserve?: any, typeMapping?: TypeMapping) {
4141
return {
4242
nextId: reply[0],
43-
messages: (reply[1] as unknown as UnwrapReply<typeof reply[1]>).map(transformStreamMessageNullReply),
43+
messages: (reply[1] as unknown as UnwrapReply<typeof reply[1]>).map(transformStreamMessageNullReply.bind(undefined, typeMapping)),
4444
deletedMessages: reply[2]
4545
};
4646
}

packages/client/lib/commands/XCLAIM.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RedisArgument, ArrayReply, NullReply, UnwrapReply, Command } from '../RESP/types';
1+
import { RedisArgument, ArrayReply, NullReply, UnwrapReply, Command, TypeMapping } from '../RESP/types';
22
import { RedisVariadicArgument, pushVariadicArguments, StreamMessageRawReply, transformStreamMessageNullReply } from './generic-transformers';
33

44
export interface XClaimOptions {
@@ -50,7 +50,11 @@ export default {
5050

5151
return args;
5252
},
53-
transformReply(reply: UnwrapReply<ArrayReply<StreamMessageRawReply | NullReply>>) {
54-
return reply.map(transformStreamMessageNullReply);
53+
transformReply(
54+
reply: UnwrapReply<ArrayReply<StreamMessageRawReply | NullReply>>,
55+
preserve?: any,
56+
typeMapping?: TypeMapping
57+
) {
58+
return reply.map(transformStreamMessageNullReply.bind(undefined, typeMapping));
5559
}
5660
} as const satisfies Command;

packages/client/lib/commands/XRANGE.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RedisArgument, ArrayReply, UnwrapReply, Command } from '../RESP/types';
1+
import { RedisArgument, ArrayReply, UnwrapReply, Command, TypeMapping } from '../RESP/types';
22
import { StreamMessageRawReply, transformStreamMessageReply } from './generic-transformers';
33

44
export interface XRangeOptions {
@@ -25,7 +25,11 @@ export default {
2525
FIRST_KEY_INDEX: 1,
2626
IS_READ_ONLY: true,
2727
transformArguments: transformXRangeArguments.bind(undefined, 'XRANGE'),
28-
transformReply(reply: UnwrapReply<ArrayReply<StreamMessageRawReply>>) {
29-
return reply.map(transformStreamMessageReply);
28+
transformReply(
29+
reply: UnwrapReply<ArrayReply<StreamMessageRawReply>>,
30+
preserve?: any,
31+
typeMapping?: TypeMapping
32+
) {
33+
return reply.map(transformStreamMessageReply.bind(undefined, typeMapping));
3034
}
3135
} as const satisfies Command;

0 commit comments

Comments
 (0)