@windrun-huaiin/backend-core 15.1.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +44 -0
  5. package/dist/index.mjs +8 -1
  6. package/dist/lib/index.js +19 -0
  7. package/dist/lib/index.mjs +1 -1
  8. package/dist/lib/upstash/qstash.d.ts +20 -7
  9. package/dist/lib/upstash/qstash.d.ts.map +1 -1
  10. package/dist/lib/upstash/qstash.js +33 -7
  11. package/dist/lib/upstash/qstash.mjs +33 -7
  12. package/dist/lib/upstash/redis-structures.d.ts +83 -0
  13. package/dist/lib/upstash/redis-structures.d.ts.map +1 -1
  14. package/dist/lib/upstash/redis-structures.js +220 -0
  15. package/dist/lib/upstash/redis-structures.mjs +202 -1
  16. package/dist/lib/upstash-config.d.ts.map +1 -1
  17. package/dist/lib/upstash-config.js +76 -4
  18. package/dist/lib/upstash-config.mjs +76 -4
  19. package/dist/services/ai/abort.d.ts +2 -0
  20. package/dist/services/ai/abort.d.ts.map +1 -0
  21. package/dist/services/ai/abort.js +24 -0
  22. package/dist/services/ai/abort.mjs +22 -0
  23. package/dist/services/ai/env.d.ts +21 -0
  24. package/dist/services/ai/env.d.ts.map +1 -0
  25. package/dist/services/ai/env.js +85 -0
  26. package/dist/services/ai/env.mjs +80 -0
  27. package/dist/services/ai/error.d.ts +3 -0
  28. package/dist/services/ai/error.d.ts.map +1 -0
  29. package/dist/services/ai/error.js +54 -0
  30. package/dist/services/ai/error.mjs +52 -0
  31. package/dist/services/ai/index.d.ts +9 -0
  32. package/dist/services/ai/index.d.ts.map +1 -0
  33. package/dist/services/ai/index.js +30 -0
  34. package/dist/services/ai/index.mjs +7 -0
  35. package/dist/services/ai/message-builder.d.ts +4 -0
  36. package/dist/services/ai/message-builder.d.ts.map +1 -0
  37. package/dist/services/ai/message-builder.js +15 -0
  38. package/dist/services/ai/message-builder.mjs +13 -0
  39. package/dist/services/ai/mock.d.ts +30 -0
  40. package/dist/services/ai/mock.d.ts.map +1 -0
  41. package/dist/services/ai/mock.js +314 -0
  42. package/dist/services/ai/mock.mjs +308 -0
  43. package/dist/services/ai/openrouter-client.d.ts +12 -0
  44. package/dist/services/ai/openrouter-client.d.ts.map +1 -0
  45. package/dist/services/ai/openrouter-client.js +81 -0
  46. package/dist/services/ai/openrouter-client.mjs +78 -0
  47. package/dist/services/ai/route.d.ts +6 -0
  48. package/dist/services/ai/route.d.ts.map +1 -0
  49. package/dist/services/ai/route.js +178 -0
  50. package/dist/services/ai/route.mjs +173 -0
  51. package/dist/services/ai/types.d.ts +98 -0
  52. package/dist/services/ai/types.d.ts.map +1 -0
  53. package/package.json +11 -4
  54. package/src/index.ts +1 -0
  55. package/src/lib/upstash/qstash.ts +55 -15
  56. package/src/lib/upstash/redis-structures.ts +248 -0
  57. package/src/lib/upstash-config.ts +106 -4
  58. package/src/services/ai/abort.ts +26 -0
  59. package/src/services/ai/env.ts +120 -0
  60. package/src/services/ai/error.ts +64 -0
  61. package/src/services/ai/index.ts +8 -0
  62. package/src/services/ai/message-builder.ts +17 -0
  63. package/src/services/ai/mock.ts +378 -0
  64. package/src/services/ai/openrouter-client.ts +94 -0
  65. package/src/services/ai/route.ts +218 -0
  66. package/src/services/ai/types.ts +131 -0
@@ -22,6 +22,30 @@ const setString = (key, value, ttlSec) => tslib.__awaiter(void 0, void 0, void 0
22
22
  const getString = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
23
23
  return upstashConfig.withRedis((redis) => redis.get(key));
24
24
  });
25
+ /**
26
+ * MGET plain string values. Missing keys are returned as null.
27
+ */
28
+ const mget = (keys) => tslib.__awaiter(void 0, void 0, void 0, function* () {
29
+ return upstashConfig.withRedis((redis) => {
30
+ if (keys.length === 0) {
31
+ return [];
32
+ }
33
+ return redis.mget(...keys);
34
+ });
35
+ });
36
+ /**
37
+ * MSET plain string values.
38
+ */
39
+ const mset = (entries) => tslib.__awaiter(void 0, void 0, void 0, function* () {
40
+ const keys = Object.keys(entries);
41
+ if (keys.length === 0) {
42
+ return true;
43
+ }
44
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
45
+ yield redis.mset(entries);
46
+ return true;
47
+ })).then((result) => result !== null && result !== void 0 ? result : false);
48
+ });
25
49
  /**
26
50
  * Store an object as JSON string with optional TTL (seconds).
27
51
  */
@@ -53,6 +77,42 @@ const getJson = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
53
77
  }
54
78
  }));
55
79
  });
80
+ /**
81
+ * MGET JSON values stored as strings. Missing or invalid values are returned as null.
82
+ */
83
+ const mgetJson = (keys) => tslib.__awaiter(void 0, void 0, void 0, function* () {
84
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
85
+ if (keys.length === 0) {
86
+ return [];
87
+ }
88
+ const payloads = yield redis.mget(...keys);
89
+ return payloads.map((payload) => {
90
+ if (!payload) {
91
+ return null;
92
+ }
93
+ try {
94
+ return JSON.parse(payload);
95
+ }
96
+ catch (_a) {
97
+ return null;
98
+ }
99
+ });
100
+ }));
101
+ });
102
+ /**
103
+ * MSET JSON values as strings.
104
+ */
105
+ const msetJson = (entries) => tslib.__awaiter(void 0, void 0, void 0, function* () {
106
+ const keys = Object.keys(entries);
107
+ if (keys.length === 0) {
108
+ return true;
109
+ }
110
+ const payloads = Object.fromEntries(Object.entries(entries).map(([key, value]) => [key, JSON.stringify(value)]));
111
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
112
+ yield redis.mset(payloads);
113
+ return true;
114
+ })).then((result) => result !== null && result !== void 0 ? result : false);
115
+ });
56
116
  /**
57
117
  * Delete a key. Returns false if Redis is unavailable.
58
118
  */
@@ -63,6 +123,45 @@ const deleteKey = (key) => tslib.__awaiter(void 0, void 0, void 0, function* ()
63
123
  }));
64
124
  return result !== null && result !== void 0 ? result : false;
65
125
  });
126
+ /**
127
+ * DEL multiple keys. Returns deleted count, or null if Redis is unavailable.
128
+ */
129
+ const del = (keys) => tslib.__awaiter(void 0, void 0, void 0, function* () {
130
+ return upstashConfig.withRedis((redis) => {
131
+ if (keys.length === 0) {
132
+ return 0;
133
+ }
134
+ return redis.del(...keys);
135
+ });
136
+ });
137
+ /**
138
+ * EXISTS a key.
139
+ */
140
+ const exists = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
141
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
142
+ const count = yield redis.exists(key);
143
+ return count > 0;
144
+ }));
145
+ });
146
+ /**
147
+ * EXPIRE a key in seconds.
148
+ */
149
+ const expire = (key, ttlSec) => tslib.__awaiter(void 0, void 0, void 0, function* () {
150
+ if (ttlSec <= 0) {
151
+ return false;
152
+ }
153
+ const result = yield upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
154
+ const changed = yield redis.expire(key, ttlSec);
155
+ return changed > 0;
156
+ }));
157
+ return result !== null && result !== void 0 ? result : false;
158
+ });
159
+ /**
160
+ * TTL for a key in seconds. Returns null if Redis is unavailable.
161
+ */
162
+ const ttl = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
163
+ return upstashConfig.withRedis((redis) => redis.ttl(key));
164
+ });
66
165
  /**
67
166
  * Set a hash field value.
68
167
  */
@@ -79,6 +178,35 @@ const setHashField = (key, field, value) => tslib.__awaiter(void 0, void 0, void
79
178
  const getHashField = (key, field) => tslib.__awaiter(void 0, void 0, void 0, function* () {
80
179
  return upstashConfig.withRedis((redis) => redis.hget(key, field));
81
180
  });
181
+ /**
182
+ * HMSET hash fields.
183
+ */
184
+ const hmset = (key, values) => tslib.__awaiter(void 0, void 0, void 0, function* () {
185
+ const fields = Object.keys(values);
186
+ if (fields.length === 0) {
187
+ return true;
188
+ }
189
+ const result = yield upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
190
+ yield redis.hset(key, values);
191
+ return true;
192
+ }));
193
+ return result !== null && result !== void 0 ? result : false;
194
+ });
195
+ /**
196
+ * HMGET hash fields.
197
+ */
198
+ const hmget = (key, fields) => tslib.__awaiter(void 0, void 0, void 0, function* () {
199
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
200
+ if (fields.length === 0) {
201
+ return {};
202
+ }
203
+ const result = yield redis.hmget(key, ...fields);
204
+ if (!result) {
205
+ return Object.fromEntries(fields.map((field) => [field, null]));
206
+ }
207
+ return result;
208
+ }));
209
+ });
82
210
  /**
83
211
  * Store a hash field as JSON string.
84
212
  */
@@ -116,6 +244,27 @@ const getHashAll = (key) => tslib.__awaiter(void 0, void 0, void 0, function* ()
116
244
  return result !== null && result !== void 0 ? result : {};
117
245
  }));
118
246
  });
247
+ /**
248
+ * HEXISTS a hash field.
249
+ */
250
+ const hexists = (key, field) => tslib.__awaiter(void 0, void 0, void 0, function* () {
251
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
252
+ const exists = yield redis.hexists(key, field);
253
+ return exists > 0;
254
+ }));
255
+ });
256
+ /**
257
+ * HKEYS for a hash.
258
+ */
259
+ const hkeys = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
260
+ return upstashConfig.withRedis((redis) => redis.hkeys(key));
261
+ });
262
+ /**
263
+ * HLEN for a hash.
264
+ */
265
+ const hlen = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
266
+ return upstashConfig.withRedis((redis) => redis.hlen(key));
267
+ });
119
268
  /**
120
269
  * Remove a hash field.
121
270
  */
@@ -126,6 +275,49 @@ const deleteHashField = (key, field) => tslib.__awaiter(void 0, void 0, void 0,
126
275
  }));
127
276
  return result !== null && result !== void 0 ? result : false;
128
277
  });
278
+ /**
279
+ * SADD members to a set. Returns count of newly added members, or null if Redis is unavailable.
280
+ */
281
+ const sadd = (key, members) => tslib.__awaiter(void 0, void 0, void 0, function* () {
282
+ return upstashConfig.withRedis((redis) => {
283
+ if (members.length === 0) {
284
+ return 0;
285
+ }
286
+ return redis.sadd(key, members[0], ...members.slice(1));
287
+ });
288
+ });
289
+ /**
290
+ * SREM members from a set. Returns count of removed members, or null if Redis is unavailable.
291
+ */
292
+ const srem = (key, members) => tslib.__awaiter(void 0, void 0, void 0, function* () {
293
+ return upstashConfig.withRedis((redis) => {
294
+ if (members.length === 0) {
295
+ return 0;
296
+ }
297
+ return redis.srem(key, ...members);
298
+ });
299
+ });
300
+ /**
301
+ * SISMEMBER for a set member.
302
+ */
303
+ const sismember = (key, member) => tslib.__awaiter(void 0, void 0, void 0, function* () {
304
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
305
+ const exists = yield redis.sismember(key, member);
306
+ return exists > 0;
307
+ }));
308
+ });
309
+ /**
310
+ * SMEMBERS for a set.
311
+ */
312
+ const smembers = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
313
+ return upstashConfig.withRedis((redis) => redis.smembers(key));
314
+ });
315
+ /**
316
+ * SCARD for a set.
317
+ */
318
+ const scard = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
319
+ return upstashConfig.withRedis((redis) => redis.scard(key));
320
+ });
129
321
  /**
130
322
  * Push values to a list. Returns list length or null if Redis is unavailable.
131
323
  */
@@ -157,19 +349,47 @@ const rangeList = (key_1, ...args_1) => tslib.__awaiter(void 0, [key_1, ...args_
157
349
  const listLength = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
158
350
  return upstashConfig.withRedis((redis) => redis.llen(key));
159
351
  });
352
+ /**
353
+ * Execute a Redis pipeline and return the result array from exec().
354
+ */
355
+ const pipeline = (build) => tslib.__awaiter(void 0, void 0, void 0, function* () {
356
+ return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
357
+ const pipeline = redis.pipeline();
358
+ return build(pipeline).exec();
359
+ }));
360
+ });
160
361
 
362
+ exports.del = del;
161
363
  exports.deleteHashField = deleteHashField;
162
364
  exports.deleteKey = deleteKey;
365
+ exports.exists = exists;
366
+ exports.expire = expire;
163
367
  exports.getHashAll = getHashAll;
164
368
  exports.getHashField = getHashField;
165
369
  exports.getHashJson = getHashJson;
166
370
  exports.getJson = getJson;
167
371
  exports.getString = getString;
372
+ exports.hexists = hexists;
373
+ exports.hkeys = hkeys;
374
+ exports.hlen = hlen;
375
+ exports.hmget = hmget;
376
+ exports.hmset = hmset;
168
377
  exports.listLength = listLength;
378
+ exports.mget = mget;
379
+ exports.mgetJson = mgetJson;
380
+ exports.mset = mset;
381
+ exports.msetJson = msetJson;
382
+ exports.pipeline = pipeline;
169
383
  exports.popList = popList;
170
384
  exports.pushList = pushList;
171
385
  exports.rangeList = rangeList;
386
+ exports.sadd = sadd;
387
+ exports.scard = scard;
172
388
  exports.setHashField = setHashField;
173
389
  exports.setHashJson = setHashJson;
174
390
  exports.setJson = setJson;
175
391
  exports.setString = setString;
392
+ exports.sismember = sismember;
393
+ exports.smembers = smembers;
394
+ exports.srem = srem;
395
+ exports.ttl = ttl;
@@ -20,6 +20,30 @@ const setString = (key, value, ttlSec) => __awaiter(void 0, void 0, void 0, func
20
20
  const getString = (key) => __awaiter(void 0, void 0, void 0, function* () {
21
21
  return withRedis((redis) => redis.get(key));
22
22
  });
23
+ /**
24
+ * MGET plain string values. Missing keys are returned as null.
25
+ */
26
+ const mget = (keys) => __awaiter(void 0, void 0, void 0, function* () {
27
+ return withRedis((redis) => {
28
+ if (keys.length === 0) {
29
+ return [];
30
+ }
31
+ return redis.mget(...keys);
32
+ });
33
+ });
34
+ /**
35
+ * MSET plain string values.
36
+ */
37
+ const mset = (entries) => __awaiter(void 0, void 0, void 0, function* () {
38
+ const keys = Object.keys(entries);
39
+ if (keys.length === 0) {
40
+ return true;
41
+ }
42
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
43
+ yield redis.mset(entries);
44
+ return true;
45
+ })).then((result) => result !== null && result !== void 0 ? result : false);
46
+ });
23
47
  /**
24
48
  * Store an object as JSON string with optional TTL (seconds).
25
49
  */
@@ -51,6 +75,42 @@ const getJson = (key) => __awaiter(void 0, void 0, void 0, function* () {
51
75
  }
52
76
  }));
53
77
  });
78
+ /**
79
+ * MGET JSON values stored as strings. Missing or invalid values are returned as null.
80
+ */
81
+ const mgetJson = (keys) => __awaiter(void 0, void 0, void 0, function* () {
82
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
83
+ if (keys.length === 0) {
84
+ return [];
85
+ }
86
+ const payloads = yield redis.mget(...keys);
87
+ return payloads.map((payload) => {
88
+ if (!payload) {
89
+ return null;
90
+ }
91
+ try {
92
+ return JSON.parse(payload);
93
+ }
94
+ catch (_a) {
95
+ return null;
96
+ }
97
+ });
98
+ }));
99
+ });
100
+ /**
101
+ * MSET JSON values as strings.
102
+ */
103
+ const msetJson = (entries) => __awaiter(void 0, void 0, void 0, function* () {
104
+ const keys = Object.keys(entries);
105
+ if (keys.length === 0) {
106
+ return true;
107
+ }
108
+ const payloads = Object.fromEntries(Object.entries(entries).map(([key, value]) => [key, JSON.stringify(value)]));
109
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
110
+ yield redis.mset(payloads);
111
+ return true;
112
+ })).then((result) => result !== null && result !== void 0 ? result : false);
113
+ });
54
114
  /**
55
115
  * Delete a key. Returns false if Redis is unavailable.
56
116
  */
@@ -61,6 +121,45 @@ const deleteKey = (key) => __awaiter(void 0, void 0, void 0, function* () {
61
121
  }));
62
122
  return result !== null && result !== void 0 ? result : false;
63
123
  });
124
+ /**
125
+ * DEL multiple keys. Returns deleted count, or null if Redis is unavailable.
126
+ */
127
+ const del = (keys) => __awaiter(void 0, void 0, void 0, function* () {
128
+ return withRedis((redis) => {
129
+ if (keys.length === 0) {
130
+ return 0;
131
+ }
132
+ return redis.del(...keys);
133
+ });
134
+ });
135
+ /**
136
+ * EXISTS a key.
137
+ */
138
+ const exists = (key) => __awaiter(void 0, void 0, void 0, function* () {
139
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
140
+ const count = yield redis.exists(key);
141
+ return count > 0;
142
+ }));
143
+ });
144
+ /**
145
+ * EXPIRE a key in seconds.
146
+ */
147
+ const expire = (key, ttlSec) => __awaiter(void 0, void 0, void 0, function* () {
148
+ if (ttlSec <= 0) {
149
+ return false;
150
+ }
151
+ const result = yield withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
152
+ const changed = yield redis.expire(key, ttlSec);
153
+ return changed > 0;
154
+ }));
155
+ return result !== null && result !== void 0 ? result : false;
156
+ });
157
+ /**
158
+ * TTL for a key in seconds. Returns null if Redis is unavailable.
159
+ */
160
+ const ttl = (key) => __awaiter(void 0, void 0, void 0, function* () {
161
+ return withRedis((redis) => redis.ttl(key));
162
+ });
64
163
  /**
65
164
  * Set a hash field value.
66
165
  */
@@ -77,6 +176,35 @@ const setHashField = (key, field, value) => __awaiter(void 0, void 0, void 0, fu
77
176
  const getHashField = (key, field) => __awaiter(void 0, void 0, void 0, function* () {
78
177
  return withRedis((redis) => redis.hget(key, field));
79
178
  });
179
+ /**
180
+ * HMSET hash fields.
181
+ */
182
+ const hmset = (key, values) => __awaiter(void 0, void 0, void 0, function* () {
183
+ const fields = Object.keys(values);
184
+ if (fields.length === 0) {
185
+ return true;
186
+ }
187
+ const result = yield withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
188
+ yield redis.hset(key, values);
189
+ return true;
190
+ }));
191
+ return result !== null && result !== void 0 ? result : false;
192
+ });
193
+ /**
194
+ * HMGET hash fields.
195
+ */
196
+ const hmget = (key, fields) => __awaiter(void 0, void 0, void 0, function* () {
197
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
198
+ if (fields.length === 0) {
199
+ return {};
200
+ }
201
+ const result = yield redis.hmget(key, ...fields);
202
+ if (!result) {
203
+ return Object.fromEntries(fields.map((field) => [field, null]));
204
+ }
205
+ return result;
206
+ }));
207
+ });
80
208
  /**
81
209
  * Store a hash field as JSON string.
82
210
  */
@@ -114,6 +242,27 @@ const getHashAll = (key) => __awaiter(void 0, void 0, void 0, function* () {
114
242
  return result !== null && result !== void 0 ? result : {};
115
243
  }));
116
244
  });
245
+ /**
246
+ * HEXISTS a hash field.
247
+ */
248
+ const hexists = (key, field) => __awaiter(void 0, void 0, void 0, function* () {
249
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
250
+ const exists = yield redis.hexists(key, field);
251
+ return exists > 0;
252
+ }));
253
+ });
254
+ /**
255
+ * HKEYS for a hash.
256
+ */
257
+ const hkeys = (key) => __awaiter(void 0, void 0, void 0, function* () {
258
+ return withRedis((redis) => redis.hkeys(key));
259
+ });
260
+ /**
261
+ * HLEN for a hash.
262
+ */
263
+ const hlen = (key) => __awaiter(void 0, void 0, void 0, function* () {
264
+ return withRedis((redis) => redis.hlen(key));
265
+ });
117
266
  /**
118
267
  * Remove a hash field.
119
268
  */
@@ -124,6 +273,49 @@ const deleteHashField = (key, field) => __awaiter(void 0, void 0, void 0, functi
124
273
  }));
125
274
  return result !== null && result !== void 0 ? result : false;
126
275
  });
276
+ /**
277
+ * SADD members to a set. Returns count of newly added members, or null if Redis is unavailable.
278
+ */
279
+ const sadd = (key, members) => __awaiter(void 0, void 0, void 0, function* () {
280
+ return withRedis((redis) => {
281
+ if (members.length === 0) {
282
+ return 0;
283
+ }
284
+ return redis.sadd(key, members[0], ...members.slice(1));
285
+ });
286
+ });
287
+ /**
288
+ * SREM members from a set. Returns count of removed members, or null if Redis is unavailable.
289
+ */
290
+ const srem = (key, members) => __awaiter(void 0, void 0, void 0, function* () {
291
+ return withRedis((redis) => {
292
+ if (members.length === 0) {
293
+ return 0;
294
+ }
295
+ return redis.srem(key, ...members);
296
+ });
297
+ });
298
+ /**
299
+ * SISMEMBER for a set member.
300
+ */
301
+ const sismember = (key, member) => __awaiter(void 0, void 0, void 0, function* () {
302
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
303
+ const exists = yield redis.sismember(key, member);
304
+ return exists > 0;
305
+ }));
306
+ });
307
+ /**
308
+ * SMEMBERS for a set.
309
+ */
310
+ const smembers = (key) => __awaiter(void 0, void 0, void 0, function* () {
311
+ return withRedis((redis) => redis.smembers(key));
312
+ });
313
+ /**
314
+ * SCARD for a set.
315
+ */
316
+ const scard = (key) => __awaiter(void 0, void 0, void 0, function* () {
317
+ return withRedis((redis) => redis.scard(key));
318
+ });
127
319
  /**
128
320
  * Push values to a list. Returns list length or null if Redis is unavailable.
129
321
  */
@@ -155,5 +347,14 @@ const rangeList = (key_1, ...args_1) => __awaiter(void 0, [key_1, ...args_1], vo
155
347
  const listLength = (key) => __awaiter(void 0, void 0, void 0, function* () {
156
348
  return withRedis((redis) => redis.llen(key));
157
349
  });
350
+ /**
351
+ * Execute a Redis pipeline and return the result array from exec().
352
+ */
353
+ const pipeline = (build) => __awaiter(void 0, void 0, void 0, function* () {
354
+ return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
355
+ const pipeline = redis.pipeline();
356
+ return build(pipeline).exec();
357
+ }));
358
+ });
158
359
 
159
- export { deleteHashField, deleteKey, getHashAll, getHashField, getHashJson, getJson, getString, listLength, popList, pushList, rangeList, setHashField, setHashJson, setJson, setString };
360
+ export { del, deleteHashField, deleteKey, exists, expire, getHashAll, getHashField, getHashJson, getJson, getString, hexists, hkeys, hlen, hmget, hmset, listLength, mget, mgetJson, mset, msetJson, pipeline, popList, pushList, rangeList, sadd, scard, setHashField, setHashJson, setJson, setString, sismember, smembers, srem, ttl };
@@ -1 +1 @@
1
- {"version":3,"file":"upstash-config.d.ts","sourceRoot":"","sources":["../../src/lib/upstash-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAoIzD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,KAAK,GAAG,IAEnC,CAAC;AAsDF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QAAO,YAAY,GAAG,IAE3C,CAAC;AAyCF,eAAO,MAAM,SAAS,GAAU,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAMzF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,CAAC,EAChC,IAAI,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAC3C,OAAO,CAAC,CAAC,GAAG,IAAI,CAMlB,CAAC"}
1
+ {"version":3,"file":"upstash-config.d.ts","sourceRoot":"","sources":["../../src/lib/upstash-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwOzD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,KAAK,GAAG,IAEnC,CAAC;AAwDF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QAAO,YAAY,GAAG,IAE3C,CAAC;AAyCF,eAAO,MAAM,SAAS,GAAU,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAMzF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,CAAC,EAChC,IAAI,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAC3C,OAAO,CAAC,CAAC,GAAG,IAAI,CAMlB,CAAC"}
@@ -19,6 +19,7 @@ let qstashWarnedHealthCheck = false;
19
19
  let qstashWarnedHealthSchedule = false;
20
20
  let redisHealthTimer = null;
21
21
  let qstashHealthTimer = null;
22
+ let cachedRedisPrefixed = null;
22
23
  const isNonEmpty = (value) => typeof value === 'string' && value.trim().length > 0;
23
24
  const isValidUrl = (value) => {
24
25
  try {
@@ -29,6 +30,75 @@ const isValidUrl = (value) => {
29
30
  return false;
30
31
  }
31
32
  };
33
+ const getRequiredRedisAppName = () => {
34
+ const appName = process.env.NEXT_PUBLIC_APP_NAME;
35
+ if (!isNonEmpty(appName)) {
36
+ throw new Error('[Upstash Config] NEXT_PUBLIC_APP_NAME is required for Redis key prefixing and must not be empty');
37
+ }
38
+ const normalized = appName.replace(/\s+/g, '').toLowerCase();
39
+ if (!normalized) {
40
+ throw new Error('[Upstash Config] NEXT_PUBLIC_APP_NAME must contain non-whitespace characters for Redis key prefixing');
41
+ }
42
+ return normalized;
43
+ };
44
+ const getRedisKeyPrefix = () => {
45
+ const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
46
+ return `${getRequiredRedisAppName()}_${envSuffix}`;
47
+ };
48
+ const prefixRedisKey = (prefix, key) => `${prefix}:${key}`;
49
+ const prefixRedisKeys = (prefix, keys) => keys.map((key) => prefixRedisKey(prefix, key));
50
+ const prefixFirstStringArg = (args, prefix) => {
51
+ if (typeof args[0] !== 'string') {
52
+ return args;
53
+ }
54
+ const nextArgs = [...args];
55
+ nextArgs[0] = prefixRedisKey(prefix, args[0]);
56
+ return nextArgs;
57
+ };
58
+ const prefixAllStringArgs = (args, prefix) => {
59
+ return args.map((arg) => (typeof arg === 'string' ? prefixRedisKey(prefix, arg) : arg));
60
+ };
61
+ const keyArrayCommands = new Set(['mget', 'del']);
62
+ const allStringKeyCommands = new Set(['exists']);
63
+ const createPrefixedPipeline = (target, prefix) => {
64
+ return new Proxy(target, {
65
+ get(obj, prop, receiver) {
66
+ const value = Reflect.get(obj, prop, receiver);
67
+ if (typeof value !== 'function') {
68
+ return value;
69
+ }
70
+ return (...args) => {
71
+ if (prop === 'eval' || prop === 'evalsha' || prop === 'evalro' || prop === 'evalshaRo') {
72
+ const [script, keys, argv] = args;
73
+ return value.call(obj, script, prefixRedisKeys(prefix, keys), argv);
74
+ }
75
+ if (prop === 'pipeline' || prop === 'multi') {
76
+ const nested = value.call(obj);
77
+ return createPrefixedPipeline(nested, prefix);
78
+ }
79
+ if (typeof prop === 'string' && keyArrayCommands.has(prop)) {
80
+ const nextArgs = prefixAllStringArgs(args, prefix);
81
+ return value.apply(obj, nextArgs);
82
+ }
83
+ if (typeof prop === 'string' && allStringKeyCommands.has(prop)) {
84
+ const nextArgs = prefixAllStringArgs(args, prefix);
85
+ return value.apply(obj, nextArgs);
86
+ }
87
+ if (prop === 'mset') {
88
+ const [entries] = args;
89
+ const prefixedEntries = Object.fromEntries(Object.entries(entries).map(([key, entryValue]) => [prefixRedisKey(prefix, key), entryValue]));
90
+ return value.call(obj, prefixedEntries);
91
+ }
92
+ if (prop === 'hmget') {
93
+ const nextArgs = prefixFirstStringArg(args, prefix);
94
+ return value.apply(obj, nextArgs);
95
+ }
96
+ const nextArgs = prefixFirstStringArg(args, prefix);
97
+ return value.apply(obj, nextArgs);
98
+ };
99
+ },
100
+ });
101
+ };
32
102
  const parseMinutes = (value, fallback) => {
33
103
  if (!isNonEmpty(value)) {
34
104
  return fallback;
@@ -131,11 +201,11 @@ const scheduleQstashHealthCheck = (token) => {
131
201
  * - read-through cached instance only
132
202
  */
133
203
  const getRedis = () => {
134
- return cachedRedis;
204
+ return cachedRedisPrefixed;
135
205
  };
136
206
  const ensureRedis = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
137
- if (cachedRedis) {
138
- return cachedRedis;
207
+ if (cachedRedisPrefixed) {
208
+ return cachedRedisPrefixed;
139
209
  }
140
210
  if (redisInitPromise) {
141
211
  return redisInitPromise;
@@ -157,14 +227,16 @@ const ensureRedis = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
157
227
  return null;
158
228
  }
159
229
  try {
230
+ const keyPrefix = getRedisKeyPrefix();
160
231
  const client = new redis.Redis({
161
232
  url: UPSTASH_REDIS_REST_URL,
162
233
  token: UPSTASH_REDIS_REST_TOKEN,
163
234
  });
164
235
  yield client.ping();
165
236
  cachedRedis = client;
237
+ cachedRedisPrefixed = createPrefixedPipeline(client, keyPrefix);
166
238
  scheduleRedisHealthCheck();
167
- return cachedRedis;
239
+ return cachedRedisPrefixed;
168
240
  }
169
241
  catch (error) {
170
242
  if (!redisWarnedInitError) {