mirror of
https://github.com/unjs/unstorage.git
synced 2025-12-08 21:26:09 +00:00
feat: add upstash driver (#500)
Co-authored-by: Matt Kane <m@mk.gg> Co-authored-by: Pooya Parsa <pooya@pi0.io>
This commit is contained in:
parent
88135c1d8c
commit
6caa7d6bb8
2
.env.example
Normal file
2
.env.example
Normal file
@ -0,0 +1,2 @@
|
||||
VITE_UPSTASH_REDIS_REST_URL=
|
||||
VITE_UPSTASH_REDIS_REST_TOKEN=
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ __*
|
||||
.vercel
|
||||
.netlify
|
||||
test/fs-storage/**
|
||||
.env
|
||||
|
||||
49
docs/2.drivers/upstash.md
Normal file
49
docs/2.drivers/upstash.md
Normal file
@ -0,0 +1,49 @@
|
||||
---
|
||||
icon: simple-icons:upstash
|
||||
---
|
||||
|
||||
# Upstash
|
||||
|
||||
> Store data in an Upstash Redis database.
|
||||
|
||||
## Usage
|
||||
|
||||
::read-more{to="https://upstash.com/"}
|
||||
Learn more about Upstash.
|
||||
::
|
||||
|
||||
::note
|
||||
Unstorage uses [`@upstash/redis`](https://github.com/upstash/upstash-redis) internally to connect to Upstash Redis.
|
||||
::
|
||||
|
||||
To use it, you will need to install `@upstash/redis` in your project:
|
||||
|
||||
:pm-install{name="@upstash/redis"}
|
||||
|
||||
Usage with Upstash Redis:
|
||||
|
||||
```js
|
||||
import { createStorage } from "unstorage";
|
||||
import upstashDriver from "unstorage/drivers/upstash";
|
||||
|
||||
const storage = createStorage({
|
||||
driver: upstashDriver({
|
||||
base: "unstorage",
|
||||
// url: "", // or set UPSTASH_REDIS_REST_URL env
|
||||
// token: "", // or set UPSTASH_REDIS_REST_TOKEN env
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
- `base`: Optional prefix to use for all keys. Can be used for namespacing.
|
||||
- `url`: The REST URL for your Upstash Redis database. Find it in [the Upstash Redis console](https://console.upstash.com/redis/). Driver uses `UPSTASH_REDIS_REST_URL` environment by default.
|
||||
- `token`: The REST token for authentication with your Upstash Redis database. Find it in [the Upstash Redis console](https://console.upstash.com/redis/). Driver uses `UPSTASH_REDIS_REST_TOKEN` environment by default.
|
||||
- `ttl`: Default TTL for all items in **seconds**.
|
||||
|
||||
See [@upstash/redis documentation](https://upstash.com/docs/redis/sdks/ts/overview) for all available options.
|
||||
|
||||
**Transaction options:**
|
||||
|
||||
- `ttl`: Supported for `setItem(key, value, { ttl: number /* seconds */ })`
|
||||
69
src/drivers/upstash.ts
Normal file
69
src/drivers/upstash.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { type RedisConfigNodejs, Redis } from "@upstash/redis";
|
||||
import { defineDriver, normalizeKey, joinKeys } from "./utils";
|
||||
|
||||
export interface UpstashOptions extends Partial<RedisConfigNodejs> {
|
||||
/**
|
||||
* Optional prefix to use for all keys. Can be used for namespacing.
|
||||
*/
|
||||
base?: string;
|
||||
|
||||
/**
|
||||
* Default TTL for all items in seconds.
|
||||
*/
|
||||
ttl?: number;
|
||||
}
|
||||
|
||||
const DRIVER_NAME = "upstash";
|
||||
|
||||
export default defineDriver<UpstashOptions, Redis>(
|
||||
(options: UpstashOptions = {}) => {
|
||||
const base = normalizeKey(options?.base);
|
||||
const r = (...keys: string[]) => joinKeys(base, ...keys);
|
||||
|
||||
let redisClient: Redis;
|
||||
const getClient = () => {
|
||||
if (redisClient) {
|
||||
return redisClient;
|
||||
}
|
||||
const url =
|
||||
options.url || globalThis.process?.env?.UPSTASH_REDIS_REST_URL;
|
||||
const token =
|
||||
options.token || globalThis.process?.env?.UPSTASH_REDIS_REST_TOKEN;
|
||||
redisClient = new Redis({ url, token, ...options });
|
||||
return redisClient;
|
||||
};
|
||||
return {
|
||||
name: DRIVER_NAME,
|
||||
getInstance: getClient,
|
||||
hasItem(key) {
|
||||
return getClient().exists(r(key)).then(Boolean);
|
||||
},
|
||||
getItem(key) {
|
||||
return getClient().get(r(key));
|
||||
},
|
||||
setItem(key, value, tOptions) {
|
||||
const ttl = tOptions?.ttl || options.ttl;
|
||||
return getClient()
|
||||
.set(r(key), value, ttl ? { ex: ttl } : undefined)
|
||||
.then(() => {});
|
||||
},
|
||||
removeItem(key) {
|
||||
return getClient()
|
||||
.del(r(key))
|
||||
.then(() => {});
|
||||
},
|
||||
getKeys(base) {
|
||||
return getClient().keys(r(base, "*"));
|
||||
},
|
||||
async clear(base) {
|
||||
const keys = await getClient().keys(r(base, "*"));
|
||||
if (keys.length === 0) {
|
||||
return;
|
||||
}
|
||||
return getClient()
|
||||
.del(...keys)
|
||||
.then(() => {});
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -27,6 +27,7 @@ export const builtinDrivers = {
|
||||
planetscale: "unstorage/drivers/planetscale",
|
||||
redis: "unstorage/drivers/redis",
|
||||
sessionStorage: "unstorage/drivers/session-storage",
|
||||
upstash: "unstorage/drivers/upstash",
|
||||
vercelKV: "unstorage/drivers/vercel-kv",
|
||||
|
||||
/** @deprecated */
|
||||
|
||||
14
test/drivers/upstash.test.ts
Normal file
14
test/drivers/upstash.test.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { describe } from "vitest";
|
||||
import { testDriver } from "./utils";
|
||||
import driver from "../../src/drivers/upstash";
|
||||
|
||||
const url = process.env.VITE_UPSTASH_REDIS_REST_URL;
|
||||
const token = process.env.VITE_UPSTASH_REDIS_REST_TOKEN;
|
||||
|
||||
describe.skipIf(!url || !token)("drivers: upstash", async () => {
|
||||
process.env.UPSTASH_REDIS_REST_URL = url;
|
||||
process.env.UPSTASH_REDIS_REST_TOKEN = token;
|
||||
testDriver({
|
||||
driver: driver({}),
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user