@veryfront/ext-cache-redis 0.1.1185 → 0.1.1188
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.
- package/README.md +29 -6
- package/esm/_dnt.polyfills.d.ts +11 -11
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +14 -13
- package/esm/extensions/ext-cache-redis/src/index.d.ts +3 -2
- package/esm/extensions/ext-cache-redis/src/index.d.ts.map +1 -1
- package/esm/extensions/ext-cache-redis/src/index.js +4 -4
- package/esm/extensions/ext-cache-redis/src/redis-cache.d.ts.map +1 -1
- package/esm/extensions/ext-cache-redis/src/redis-cache.js +24 -2
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> **Category:** Storage | **Contract:** `TokenCacheStore` | **Optional**
|
|
4
4
|
|
|
5
|
-
Provides Redis-backed token
|
|
5
|
+
Provides Redis-backed token-cache persistence for Veryfront. The proxy uses it
|
|
6
|
+
to share OAuth tokens across processes. Explicit Redis selection is fail-closed:
|
|
7
|
+
startup and operations surface missing configuration or service failures.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -18,10 +20,12 @@ export default defineConfig({
|
|
|
18
20
|
|
|
19
21
|
## Environment Variables
|
|
20
22
|
|
|
21
|
-
| Variable
|
|
22
|
-
|
|
|
23
|
-
| `REDIS_URL`
|
|
24
|
-
| `REDIS_PREFIX`
|
|
23
|
+
| Variable | Required | Description |
|
|
24
|
+
| ---------------- | ------------------------------ | -------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `REDIS_URL` | Yes (if explicit config unset) | Redis connection URL, for example `redis://localhost:6379` or `rediss://...` (TLS) |
|
|
26
|
+
| `REDIS_PREFIX` | No | Token-key prefix (default: `vf:token:`); see prefix constraints below |
|
|
27
|
+
| `REDIS_PASSWORD` | No | Password override when credentials are not embedded in the connection URL |
|
|
28
|
+
| `CACHE_TYPE` | Standalone proxy only | Set to `extension` so the CLI activates this extension before importing the provider-neutral proxy |
|
|
25
29
|
|
|
26
30
|
Explicit config under `ctx.config.proxy.cache.redis` wins over env vars.
|
|
27
31
|
|
|
@@ -49,9 +53,28 @@ config = {
|
|
|
49
53
|
|
|
50
54
|
`url` is required; the rest are optional.
|
|
51
55
|
|
|
56
|
+
For the standalone CLI proxy, select and configure the extension before
|
|
57
|
+
startup:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
CACHE_TYPE=extension \
|
|
61
|
+
REDIS_URL=redis://localhost:6379 \
|
|
62
|
+
veryfront serve --mode=proxy
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The CLI activates `@veryfront/ext-cache-redis` through the extension loader
|
|
66
|
+
before it imports the proxy runtime. Missing packages, missing Redis
|
|
67
|
+
configuration, or a missing `TokenCacheStore` contract stop startup. The
|
|
68
|
+
loader retains ownership of the store; the proxy borrows it and does not close
|
|
69
|
+
it independently. `REDIS_PREFIX` in this path must contain 1 to 256 visible
|
|
70
|
+
ASCII characters and cannot contain Redis glob metacharacters (`*`, `?`, `[`,
|
|
71
|
+
`]`, or `\`).
|
|
72
|
+
|
|
52
73
|
## Provided contract
|
|
53
74
|
|
|
54
|
-
`TokenCacheStore
|
|
75
|
+
`TokenCacheStore`: `get(key)`, `set(key, entry)`, `delete(key)`, `clear()`,
|
|
76
|
+
`has(key)`, `stats()`, and `close()`. Entry expiry is carried in
|
|
77
|
+
`entry.expiresAt`. The proxy uses the contract for OAuth service-token caching.
|
|
55
78
|
|
|
56
79
|
## Capabilities
|
|
57
80
|
|
package/esm/_dnt.polyfills.d.ts
CHANGED
|
@@ -4,6 +4,17 @@ declare global {
|
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
export {};
|
|
7
|
+
declare global {
|
|
8
|
+
interface Object {
|
|
9
|
+
/**
|
|
10
|
+
* Determines whether an object has a property with the specified name.
|
|
11
|
+
* @param o An object.
|
|
12
|
+
* @param v A property name.
|
|
13
|
+
*/
|
|
14
|
+
hasOwn(o: object, v: PropertyKey): boolean;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
7
18
|
/**
|
|
8
19
|
* Based on [import-meta-ponyfill](https://github.com/gaubee/import-meta-ponyfill),
|
|
9
20
|
* but instead of using npm to install additional dependencies,
|
|
@@ -123,15 +134,4 @@ declare global {
|
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
136
|
export {};
|
|
126
|
-
declare global {
|
|
127
|
-
interface Object {
|
|
128
|
-
/**
|
|
129
|
-
* Determines whether an object has a property with the specified name.
|
|
130
|
-
* @param o An object.
|
|
131
|
-
* @param v A property name.
|
|
132
|
-
*/
|
|
133
|
-
hasOwn(o: object, v: PropertyKey): boolean;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
export {};
|
|
137
137
|
//# sourceMappingURL=_dnt.polyfills.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CACF;AAED,OAAO,EAAE,CAAC;AACV;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAgC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB;;;;;;;;;;;;;;WAcG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;;;;;;;;;;;WAYG;QACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,GAAG,MAAM,CAAC;QACtE;;;;;;;;WAQG;QACH,IAAI,EAAE,OAAO,CAAC;QAEd;;;;;;;;;;;;WAYG;QACH,QAAQ,EAAE,MAAM,CAAC;QAEjB;;;;;;;;;;;;WAYG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB;CACF;AAED,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,KAAK,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,UAAU,0BAA0B;IAClC,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACxD;AACD,UAAU,0BAA0B;IAClC,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;CACtC;AACD,UAAU,kBACR,SAAQ,0BAA0B,EAAE,0BAA0B;CAC/D;AAiBD,eAAO,IAAI,6BAA6B,EA2BnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,6BAA6B,EA4DnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,oBAAoB,EAoB1B,kBAAkB,CAAC;AACxB,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,kBAAkB;QAC1B;;;WAGG;QACH,aAAa,CAAC,CAAC,KAAK;YAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;SAAE,CAAC;KAC3H;CACF;AAcD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,gBAAgB;QACxB,SAAS,CAAC,CAAC,EACP,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAC7F,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QAEhB,SAAS,CAAC,CAAC,EAAE,CAAC,EACV,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAClE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAC/B,OAAO,CAAC,EAAE,GAAG,GACd,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC1B;CACF;AAoID,OAAO,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CACF;AAED,OAAO,EAAE,CAAC;AAgBV,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd;;;;WAIG;QACH,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;KAC5C;CACF;AAED,OAAO,EAAE,CAAC;AACV;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAgC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB;;;;;;;;;;;;;;WAcG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;;;;;;;;;;;WAYG;QACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,GAAG,MAAM,CAAC;QACtE;;;;;;;;WAQG;QACH,IAAI,EAAE,OAAO,CAAC;QAEd;;;;;;;;;;;;WAYG;QACH,QAAQ,EAAE,MAAM,CAAC;QAEjB;;;;;;;;;;;;WAYG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB;CACF;AAED,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,KAAK,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,UAAU,0BAA0B;IAClC,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACxD;AACD,UAAU,0BAA0B;IAClC,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;CACtC;AACD,UAAU,kBACR,SAAQ,0BAA0B,EAAE,0BAA0B;CAC/D;AAiBD,eAAO,IAAI,6BAA6B,EA2BnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,6BAA6B,EA4DnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,oBAAoB,EAoB1B,kBAAkB,CAAC;AACxB,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,kBAAkB;QAC1B;;;WAGG;QACH,aAAa,CAAC,CAAC,KAAK;YAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;SAAE,CAAC;KAC3H;CACF;AAcD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,gBAAgB;QACxB,SAAS,CAAC,CAAC,EACP,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAC7F,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QAEhB,SAAS,CAAC,CAAC,EAAE,CAAC,EACV,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAClE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAC/B,OAAO,CAAC,EAAE,GAAG,GACd,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC1B;CACF;AAoID,OAAO,EAAE,CAAC"}
|
package/esm/_dnt.polyfills.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
|
|
2
|
+
if (!Object.hasOwn) {
|
|
3
|
+
Object.defineProperty(Object, "hasOwn", {
|
|
4
|
+
value: function (object, property) {
|
|
5
|
+
if (object == null) {
|
|
6
|
+
throw new TypeError("Cannot convert undefined or null to object");
|
|
7
|
+
}
|
|
8
|
+
return Object.prototype.hasOwnProperty.call(Object(object), property);
|
|
9
|
+
},
|
|
10
|
+
configurable: true,
|
|
11
|
+
enumerable: false,
|
|
12
|
+
writable: true,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
1
15
|
/**
|
|
2
16
|
* Based on [import-meta-ponyfill](https://github.com/gaubee/import-meta-ponyfill),
|
|
3
17
|
* but instead of using npm to install additional dependencies,
|
|
@@ -245,16 +259,3 @@ async function fromAsync(items, mapfn, thisArg) {
|
|
|
245
259
|
if (!Array.fromAsync) {
|
|
246
260
|
Array.fromAsync = fromAsync;
|
|
247
261
|
}
|
|
248
|
-
if (!Object.hasOwn) {
|
|
249
|
-
Object.defineProperty(Object, "hasOwn", {
|
|
250
|
-
value: function (object, property) {
|
|
251
|
-
if (object == null) {
|
|
252
|
-
throw new TypeError("Cannot convert undefined or null to object");
|
|
253
|
-
}
|
|
254
|
-
return Object.prototype.hasOwnProperty.call(Object(object), property);
|
|
255
|
-
},
|
|
256
|
-
configurable: true,
|
|
257
|
-
enumerable: false,
|
|
258
|
-
writable: true,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
* };
|
|
21
21
|
* }
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* An explicitly activated extension may read `REDIS_URL` / `REDIS_PREFIX`
|
|
24
|
+
* when its config path is not populated. Missing connection configuration is
|
|
25
|
+
* a startup error rather than a silent no-op.
|
|
25
26
|
*
|
|
26
27
|
* @module extensions/ext-cache-redis
|
|
27
28
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-cache-redis/src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-cache-redis/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,4BAA4B,CAAC;AAKpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAwCzE,QAAA,MAAM,QAAQ,EAAE,gBAqDf,CAAC;AAEF,eAAe,QAAQ,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
* };
|
|
21
21
|
* }
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* An explicitly activated extension may read `REDIS_URL` / `REDIS_PREFIX`
|
|
24
|
+
* when its config path is not populated. Missing connection configuration is
|
|
25
|
+
* a startup error rather than a silent no-op.
|
|
25
26
|
*
|
|
26
27
|
* @module extensions/ext-cache-redis
|
|
27
28
|
*/
|
|
@@ -74,8 +75,7 @@ const extRedis = () => {
|
|
|
74
75
|
const cfg = readRedisConfig(ctx.config);
|
|
75
76
|
const url = cfg.url ?? readEnv("REDIS_URL");
|
|
76
77
|
if (!url) {
|
|
77
|
-
|
|
78
|
-
return;
|
|
78
|
+
throw new TypeError("ext-cache-redis requires proxy.cache.redis.url or REDIS_URL");
|
|
79
79
|
}
|
|
80
80
|
const options = {
|
|
81
81
|
url,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-cache.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-cache-redis/src/redis-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-cache.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-cache-redis/src/redis-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAgDpG,sDAAsD;AACtD,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAkBD,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,CAE/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACtB,eAAe,CAAC;AAErB,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAS;gBAGxB,OAAO,EAAE,2BAA2B,EACpC,IAAI,GAAE;QACJ,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,aAAa,CAAC,EAAE,kBAAkB,CAAC;KAC/B;IAYR,OAAO,CAAC,GAAG;IAIL,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA8BjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAevD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAalC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsCtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAalC,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAgBjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBd,kBAAkB;YAQlB,eAAe;CAsC9B"}
|
|
@@ -11,6 +11,7 @@ import { createClient } from "redis";
|
|
|
11
11
|
const DEFAULT_PREFIX = "vf:token:";
|
|
12
12
|
const DEFAULT_CONNECT_TIMEOUT_MS = 5_000;
|
|
13
13
|
const DEFAULT_SCAN_COUNT = 100;
|
|
14
|
+
const MAX_PREFIX_CODE_UNITS = 256;
|
|
14
15
|
const MAX_RECONNECT_RETRIES = 3;
|
|
15
16
|
const RECONNECT_BACKOFF_BASE_MS = 100;
|
|
16
17
|
const RECONNECT_BACKOFF_MAX_MS = 3_000;
|
|
@@ -21,6 +22,27 @@ const EXPECTED_DISCONNECT_PATTERNS = [
|
|
|
21
22
|
"econnreset",
|
|
22
23
|
"etimedout",
|
|
23
24
|
];
|
|
25
|
+
function validatePrefix(prefix) {
|
|
26
|
+
if (typeof prefix !== "string" ||
|
|
27
|
+
prefix.length === 0 ||
|
|
28
|
+
prefix.length > MAX_PREFIX_CODE_UNITS) {
|
|
29
|
+
throw new TypeError("Redis token-cache prefix must contain 1 to 256 visible ASCII characters without glob metacharacters");
|
|
30
|
+
}
|
|
31
|
+
for (let index = 0; index < prefix.length; index += 1) {
|
|
32
|
+
const code = prefix.charCodeAt(index);
|
|
33
|
+
if (code < 0x21 ||
|
|
34
|
+
code > 0x7e ||
|
|
35
|
+
code === 0x2a || // *
|
|
36
|
+
code === 0x3f || // ?
|
|
37
|
+
code === 0x5b || // [
|
|
38
|
+
code === 0x5c || // \
|
|
39
|
+
code === 0x5d // ]
|
|
40
|
+
) {
|
|
41
|
+
throw new TypeError("Redis token-cache prefix must contain 1 to 256 visible ASCII characters without glob metacharacters");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return prefix;
|
|
45
|
+
}
|
|
24
46
|
const NOOP_LOGGER = {
|
|
25
47
|
debug: () => { },
|
|
26
48
|
info: () => { },
|
|
@@ -49,7 +71,7 @@ export class RedisTokenCacheStore {
|
|
|
49
71
|
connected = false;
|
|
50
72
|
constructor(options, deps = {}) {
|
|
51
73
|
this.url = options.url;
|
|
52
|
-
this.prefix = options.prefix ?? DEFAULT_PREFIX;
|
|
74
|
+
this.prefix = validatePrefix(options.prefix ?? DEFAULT_PREFIX);
|
|
53
75
|
this.connectTimeout = options.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
54
76
|
this.tls = options.tls ?? options.url.startsWith("rediss://");
|
|
55
77
|
this.password = options.password;
|
|
@@ -171,7 +193,7 @@ export class RedisTokenCacheStore {
|
|
|
171
193
|
error: error instanceof Error ? error.message : String(error),
|
|
172
194
|
});
|
|
173
195
|
}
|
|
174
|
-
return { hits: this.hits, misses: this.misses, size, type: "
|
|
196
|
+
return { hits: this.hits, misses: this.misses, size, type: "extension" };
|
|
175
197
|
}
|
|
176
198
|
async close() {
|
|
177
199
|
const client = this.client;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veryfront/ext-cache-redis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1188",
|
|
4
4
|
"description": "Veryfront first-party extension package for ext-cache-redis",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"veryfront",
|
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
},
|
|
28
28
|
"scripts": {},
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22.3.0"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"veryfront": {
|
|
36
36
|
"extension": true,
|
|
37
|
+
"activation": "explicit",
|
|
37
38
|
"contracts": {
|
|
38
39
|
"provides": [
|
|
39
40
|
"TokenCacheStore"
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"redis": "5.11.0"
|
|
64
65
|
},
|
|
65
66
|
"peerDependencies": {
|
|
66
|
-
"veryfront": "^0.1.
|
|
67
|
+
"veryfront": "^0.1.1188"
|
|
67
68
|
},
|
|
68
69
|
"type": "module",
|
|
69
70
|
"types": "./esm/extensions/ext-cache-redis/src/index.d.ts",
|