@voyant-travel/hono 0.132.0 → 0.133.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.
@@ -125,6 +125,7 @@ export declare function createMemoryRateLimitStore(options?: {
125
125
  }): RateLimitStore;
126
126
  export interface RedisRateLimitStoreOptions {
127
127
  client?: LazyRedisClient;
128
+ keyPrefix?: string;
128
129
  }
129
130
  export declare function createRedisRateLimitStore(redisUrl: string, options?: RedisRateLimitStoreOptions): RateLimitStore;
130
131
  /** Test-only: re-arm the once-per-isolate missing-store warning. */
@@ -67,14 +67,31 @@ export function createMemoryRateLimitStore(options) {
67
67
  },
68
68
  };
69
69
  }
70
+ function normalizeRedisRateLimitKeyPrefix(keyPrefix) {
71
+ if (keyPrefix === undefined || keyPrefix.length === 0)
72
+ return "";
73
+ if (hasControlCharacter(keyPrefix)) {
74
+ throw new Error("Redis rate-limit keyPrefix must not contain control characters.");
75
+ }
76
+ return keyPrefix;
77
+ }
78
+ function hasControlCharacter(value) {
79
+ for (let index = 0; index < value.length; index += 1) {
80
+ const code = value.charCodeAt(index);
81
+ if (code <= 0x1f || code === 0x7f)
82
+ return true;
83
+ }
84
+ return false;
85
+ }
70
86
  export function createRedisRateLimitStore(redisUrl, options = {}) {
71
87
  const lazyClient = options.client ?? createLazyRedisClient(redisUrl);
88
+ const keyPrefix = normalizeRedisRateLimitKeyPrefix(options.keyPrefix);
72
89
  return {
73
90
  async limit(key, { max, windowSeconds }) {
74
91
  const client = await lazyClient.get();
75
92
  const nowSeconds = Math.floor(Date.now() / 1000);
76
93
  const windowKey = Math.floor(nowSeconds / windowSeconds);
77
- const storageKey = `${key}:${windowKey}`;
94
+ const storageKey = `${keyPrefix}${key}:${windowKey}`;
78
95
  const count = await client.incr(storageKey);
79
96
  if (count === 1) {
80
97
  await client.expire(storageKey, Math.max(1, windowSeconds * 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/hono",
3
- "version": "0.132.0",
3
+ "version": "0.133.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -133,14 +133,14 @@
133
133
  "@voyant-travel/core": "^0.130.0",
134
134
  "@voyant-travel/db": "^0.117.1",
135
135
  "@voyant-travel/types": "^0.109.8",
136
- "@voyant-travel/utils": "^0.108.0",
137
- "@voyant-travel/workflows": "^0.122.15"
136
+ "@voyant-travel/utils": "^0.109.0",
137
+ "@voyant-travel/workflows": "^0.122.18"
138
138
  },
139
139
  "devDependencies": {
140
140
  "typescript": "^6.0.3",
141
141
  "vitest": "^4.1.9",
142
142
  "@voyant-travel/voyant-typescript-config": "^0.1.0",
143
- "@voyant-travel/workflows-orchestrator": "^0.122.15"
143
+ "@voyant-travel/workflows-orchestrator": "^0.122.18"
144
144
  },
145
145
  "files": [
146
146
  "dist"