-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
full type safety and pipeline support (#22)
* feat: commands and basic tests for strings * feat: hash commands * fix: remove not supported commands * fix: remove not supported commands * feat: start work on keys * feat: list commands * feat: even more commands * feat: even more commands * feat: add remaining commands * feat: redis and pipeline command proxy * ci: add new ci pipeline * feat: pipeline improvements and tests * feat: add deserializer * test: add tests for scan * chore: minor changes and more tests * docs: annotate deserializer function * feat: static fromEnv methods * ci: limit test to this package * test: nextjs example * fix: nextjs example redis usage * ci: use reusable workflow to setup redis * fix: load cf env * ci: cloudflare example * fix: import paths
- Loading branch information
Showing
394 changed files
with
17,161 additions
and
14,065 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
module.exports = { | ||
env: { | ||
node: true, | ||
}, | ||
root: true, | ||
parser: "@typescript-eslint/parser", | ||
parserOptions: { | ||
project: "./tsconfig.json", | ||
}, | ||
plugins: ["@typescript-eslint", "prettier"], | ||
extends: [ | ||
/* | ||
* Always a good idea to start with sane defaults | ||
*/ | ||
"eslint:recommended", | ||
|
||
/* | ||
* Required to integrate prettier into eslint | ||
*/ | ||
"plugin:prettier/recommended", | ||
], | ||
rules: { | ||
semi: "off", | ||
|
||
/* | ||
* This reads all definitions from a local prettier config file and applies the correct | ||
* eslint rules automatically. | ||
*/ | ||
"prettier/prettier": ["error"], | ||
|
||
/* | ||
* Named exports are almost always better because they break when the imported module changes | ||
*/ | ||
"import/prefer-default-export": "off", | ||
|
||
"no-unused-vars": "off", | ||
"@typescript-eslint/no-unused-vars": ["error"], | ||
"object-curly-newline": "off", | ||
"max-len": [ | ||
2, | ||
{ | ||
code: 100, | ||
ignoreUrls: true, | ||
ignoreStrings: true, | ||
ignoreTemplateLiterals: true, | ||
}, | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# Upstash Redis | ||
|
||
An HTTP/REST based Redis client built on top of | ||
[Upstash REST API](https://docs.upstash.com/features/restapi). | ||
|
||
[![Tests](https://github.com/upstash/upstash-redis/actions/workflows/test.yml/badge.svg)](https://github.com/upstash/upstash-redis/actions/workflows/test.yml) | ||
![npm (scoped)](https://img.shields.io/npm/v/@upstash/redis) | ||
![npm bundle size](https://img.shields.io/bundlephobia/minzip/@upstash/redis) | ||
|
||
It is the only connectionless (HTTP based) Redis client and designed for: | ||
|
||
- Serverless functions (AWS Lambda ...) | ||
- Cloudflare Workers (see | ||
[the example](https://github.com/upstash/upstash-redis/tree/master/examples/cloudflare-workers)) | ||
- Fastly Compute@Edge | ||
- Next.js, Jamstack ... | ||
- Client side web/mobile applications | ||
- WebAssembly | ||
- and other environments where HTTP is preferred over TCP. | ||
|
||
See | ||
[the list of APIs](https://docs.upstash.com/features/restapi#rest---redis-api-compatibility) | ||
supported. | ||
|
||
## Quick Start | ||
|
||
### Install | ||
|
||
```bash | ||
npm install @upstash/redis | ||
``` | ||
|
||
```ts | ||
import { Redis } from "@upstash/redis" | ||
|
||
const redis = new Redis({ | ||
url: <UPSTASH_REDIS_REST_URL>, | ||
token: <UPSTASH_REDIS_REST_TOKEN>, | ||
}) | ||
|
||
|
||
const data = await redis.get("key) | ||
|
||
``` | ||
#### Automatic authentication from environment variables | ||
If you have added `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` as environent variables, you can automatically load them: | ||
```ts | ||
import { Redis } from "@upstash/redis" | ||
|
||
const redis = Redis.fromEnv() | ||
|
||
// or on cloudflare workers | ||
const redis = Redis.fromCloudflareEnv() | ||
``` | ||
### Working with types | ||
Most commands allow you to provide a type to make working with typescript easier. | ||
```ts | ||
const data = await redis.get<MyCustomType>("key") | ||
// data is typed as `MyCustomType` | ||
``` | ||
## Migrating to v1 | ||
### API changes | ||
### Explicit authentication | ||
Authentication is no longer automatically trying to load connection secrets from environment variables. | ||
You must either supply them yourself: | ||
```ts | ||
import { Redis } from "@upstash/redis" | ||
|
||
const redis = new Redis({ | ||
url: <UPSTASH_REDIS_REST_URL>, | ||
token: <UPSTASH_REDIS_REST_TOKEN>, | ||
}) | ||
``` | ||
Or use one of the static constructors to load from environment variables: | ||
```ts | ||
import { Redis } from "@upstash/redis" | ||
|
||
const redis = Redis.fromEnv() | ||
|
||
// or when deploying to cloudflare workers | ||
const redis = Redis.fromCloudflareEnv() | ||
``` | ||
### Error handling | ||
Errors are now thrown automatically instead of being returned to you. | ||
```ts | ||
// old | ||
const { data, error } = await set("key", "value") | ||
if (error) { | ||
throw new Error(error) | ||
} | ||
|
||
// new | ||
const data = await redis.set("key", "value") // error is thrown automatically | ||
``` | ||
### Pipeline | ||
Pipelining commands allows you to send a single http request with multiple commands. | ||
```ts | ||
import { Redis } from "@upstash/redis" | ||
|
||
const redis = new Redis({ | ||
url: <UPSTASH_REDIS_REST_URL>, | ||
token: <UPSTASH_REDIS_REST_TOKEN>, | ||
}) | ||
|
||
const p = redis.pipeline() | ||
|
||
// Now you can chain multiple commands to create your pipeline: | ||
|
||
p.set("key",2) | ||
p.incr("key") | ||
|
||
// or inline: | ||
p.hset("key2", "field", { hello: "world" }).hvals("key2") | ||
|
||
// Execute the pipeline once you are done building it: | ||
// `exec` returns an array where each element represents the response of a command in the pipeline. | ||
// You can optionally provide a type like this to get a typed response. | ||
const res = await p.exec<[Type1, Type2, Type3]>() | ||
|
||
``` | ||
For more information about pipelines using REST see [here](https://blog.upstash.com/pipeline). | ||
### Advanded | ||
Low level `Command` classes can be imported from `@upstash/redis/commands`. | ||
`Redis` is just a wrapper around these commands for your convenience. | ||
In case you need more control about types and or (de)serialization, please use a `Command`-class directly. | ||
```ts | ||
import { GetCommand, HttpClient} from "@upstash/redis" | ||
|
||
const client = new HttpClient({ | ||
baseUrl: <UPSTASH_REDIS_REST_URL>, | ||
headers: { | ||
authorization: `Bearer ${<UPSTASH_REDIS_REST_TOKEN>}`, | ||
}, | ||
}) | ||
|
||
const get = new GetCommand<OptionalCustomType>("key") | ||
|
||
const data = await get.exec(client) | ||
``` | ||
## Docs | ||
See [the documentation](https://docs.upstash.com/features/javascriptsdk) for | ||
details. | ||
## Contributing | ||
### Installing dependencies | ||
```bash | ||
pnpm install | ||
``` | ||
### Database | ||
Create a new redis database on [upstash](https://console.upstash.com/) and copy the url and token to `.env` (See `.env.example` for reference) | ||
### Running tests | ||
```sh | ||
pnpm test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
name: Create local redis server | ||
|
||
inputs: | ||
UPSTASH_REDIS_REST_URL: | ||
required: true | ||
UPSTASH_REDIS_REST_TOKEN: | ||
required: true | ||
UPSTASH_REPO_ACCESS_TOKEN: | ||
required: true | ||
REDIS_SERVER_CONFIG: | ||
required: true | ||
|
||
runs: | ||
using: "composite" | ||
|
||
steps: | ||
- name: Check out Redis Server | ||
uses: actions/checkout@v2 | ||
with: | ||
repository: upstash/redis-server | ||
token: ${{ inputs.UPSTASH_REPO_ACCESS_TOKEN }} | ||
path: redis-server | ||
|
||
- uses: actions/setup-go@v2 | ||
with: | ||
stable: "true" | ||
go-version: "^1.17" | ||
|
||
- uses: actions/cache@v2 | ||
with: | ||
path: | | ||
~/go/pkg/mod | ||
~/.cache/go-build | ||
key: ${{ runner.os }}-redis-server-${{ hashFiles('**/go.mod') }} | ||
restore-keys: | | ||
${{ runner.os }}-redis-server | ||
- run: | | ||
echo "$REDIS_SERVER_CONFIG" >> config.json | ||
shell: bash | ||
env: | ||
REDIS_SERVER_CONFIG: ${{ inputs.REDIS_SERVER_CONFIG }} | ||
- run: | | ||
make | ||
./upstash-redis -log-level error -config $GITHUB_WORKSPACE/config.json & | ||
working-directory: ./redis-server/cmd | ||
shell: bash | ||
env: | ||
UPSTASH_REDIS_REST_URL: ${{ inputs.UPSTASH_REDIS_REST_URL }} | ||
UPSTASH_REDIS_REST_TOKEN: ${{ inputs.UPSTASH_REDIS_REST_TOKEN }} | ||
- run: | | ||
curl $UPSTASH_REDIS_REST_URL/info -H "Authorization: Bearer $UPSTASH_REDIS_REST_TOKEN" | ||
shell: bash | ||
env: | ||
UPSTASH_REDIS_REST_URL: ${{ inputs.UPSTASH_REDIS_REST_URL }} | ||
UPSTASH_REDIS_REST_TOKEN: ${{ inputs.UPSTASH_REDIS_REST_TOKEN }} |
Oops, something went wrong.