@upstash/redis 0.0.0-ci.e3757170 → 0.0.0-ci.e5c2b594-20231017
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 +42 -278
- package/esm/deps/deno.land/x/base64@v0.2.1/base.js +100 -0
- package/esm/deps/deno.land/x/base64@v0.2.1/base64url.js +9 -0
- package/esm/deps/deno.land/x/sha1@v1.0.3/deps.js +1 -0
- package/esm/deps/deno.land/x/sha1@v1.0.3/mod.js +191 -0
- package/esm/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.js +50 -0
- package/esm/pkg/commands/command.js +12 -3
- package/esm/pkg/commands/getdel.js +9 -0
- package/esm/pkg/commands/hgetall.js +0 -4
- package/esm/pkg/commands/hrandfield.js +39 -0
- package/esm/pkg/commands/json_arrappend.js +9 -0
- package/esm/pkg/commands/json_arrindex.js +9 -0
- package/esm/pkg/commands/json_arrinsert.js +9 -0
- package/esm/pkg/commands/json_arrlen.js +9 -0
- package/esm/pkg/commands/json_arrpop.js +9 -0
- package/esm/pkg/commands/json_arrtrim.js +12 -0
- package/esm/pkg/commands/json_clear.js +9 -0
- package/esm/pkg/commands/json_del.js +9 -0
- package/esm/pkg/commands/json_forget.js +9 -0
- package/esm/pkg/commands/json_get.js +30 -0
- package/esm/pkg/commands/json_mget.js +9 -0
- package/esm/pkg/commands/json_numincrby.js +9 -0
- package/esm/pkg/commands/json_nummultby.js +9 -0
- package/esm/pkg/commands/json_objkeys.js +9 -0
- package/esm/pkg/commands/json_objlen.js +9 -0
- package/esm/pkg/commands/json_resp.js +9 -0
- package/esm/pkg/commands/json_set.js +18 -0
- package/esm/pkg/commands/json_strappend.js +9 -0
- package/esm/pkg/commands/json_strlen.js +9 -0
- package/esm/pkg/commands/json_toggle.js +9 -0
- package/esm/pkg/commands/json_type.js +9 -0
- package/esm/pkg/commands/lmove.js +9 -0
- package/esm/pkg/commands/lpos.js +19 -0
- package/esm/pkg/commands/mod.js +28 -0
- package/esm/pkg/commands/scan.js +3 -0
- package/esm/pkg/commands/sdiffstore.js +1 -1
- package/esm/pkg/commands/set.js +16 -4
- package/esm/pkg/commands/smismember.js +9 -0
- package/esm/pkg/commands/xadd.js +26 -0
- package/esm/pkg/commands/xrange.js +36 -0
- package/esm/pkg/commands/zdiffstore.js +9 -0
- package/esm/pkg/commands/zmscore.js +10 -0
- package/esm/pkg/commands/zrange.js +6 -0
- package/esm/pkg/http.js +100 -3
- package/esm/pkg/pipeline.js +179 -12
- package/esm/pkg/redis.js +241 -2
- package/esm/pkg/script.js +77 -0
- package/esm/platforms/cloudflare.js +10 -2
- package/esm/platforms/fastly.js +6 -0
- package/esm/platforms/node_with_fetch.js +26 -1
- package/esm/platforms/nodejs.js +24 -1
- package/esm/version.js +1 -0
- package/package.json +53 -58
- package/script/deps/deno.land/x/base64@v0.2.1/base.js +104 -0
- package/script/deps/deno.land/x/base64@v0.2.1/base64url.js +13 -0
- package/script/deps/deno.land/x/sha1@v1.0.3/deps.js +6 -0
- package/script/deps/deno.land/x/sha1@v1.0.3/mod.js +196 -0
- package/script/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.js +55 -0
- package/script/pkg/commands/command.js +12 -3
- package/script/pkg/commands/getdel.js +13 -0
- package/script/pkg/commands/hgetall.js +0 -4
- package/script/pkg/commands/hrandfield.js +43 -0
- package/script/pkg/commands/json_arrappend.js +13 -0
- package/script/pkg/commands/json_arrindex.js +13 -0
- package/script/pkg/commands/json_arrinsert.js +13 -0
- package/script/pkg/commands/json_arrlen.js +13 -0
- package/script/pkg/commands/json_arrpop.js +13 -0
- package/script/pkg/commands/json_arrtrim.js +16 -0
- package/script/pkg/commands/json_clear.js +13 -0
- package/script/pkg/commands/json_del.js +13 -0
- package/script/pkg/commands/json_forget.js +13 -0
- package/script/pkg/commands/json_get.js +34 -0
- package/script/pkg/commands/json_mget.js +13 -0
- package/script/pkg/commands/json_numincrby.js +13 -0
- package/script/pkg/commands/json_nummultby.js +13 -0
- package/script/pkg/commands/json_objkeys.js +13 -0
- package/script/pkg/commands/json_objlen.js +13 -0
- package/script/pkg/commands/json_resp.js +13 -0
- package/script/pkg/commands/json_set.js +22 -0
- package/script/pkg/commands/json_strappend.js +13 -0
- package/script/pkg/commands/json_strlen.js +13 -0
- package/script/pkg/commands/json_toggle.js +13 -0
- package/script/pkg/commands/json_type.js +13 -0
- package/script/pkg/commands/lmove.js +13 -0
- package/script/pkg/commands/lpos.js +23 -0
- package/script/pkg/commands/mod.js +28 -0
- package/script/pkg/commands/scan.js +3 -0
- package/script/pkg/commands/sdiffstore.js +1 -1
- package/script/pkg/commands/set.js +16 -4
- package/script/pkg/commands/smismember.js +13 -0
- package/script/pkg/commands/xadd.js +30 -0
- package/script/pkg/commands/xrange.js +40 -0
- package/script/pkg/commands/zdiffstore.js +13 -0
- package/script/pkg/commands/zmscore.js +14 -0
- package/script/pkg/commands/zrange.js +6 -0
- package/script/pkg/http.js +100 -3
- package/script/pkg/pipeline.js +178 -11
- package/script/pkg/redis.js +240 -1
- package/script/pkg/script.js +81 -0
- package/script/platforms/cloudflare.js +10 -2
- package/script/platforms/fastly.js +6 -0
- package/script/platforms/node_with_fetch.js +26 -1
- package/script/platforms/nodejs.js +24 -1
- package/script/version.js +4 -0
- package/types/deps/deno.land/x/base64@v0.2.1/base.d.ts +5 -0
- package/types/deps/deno.land/x/base64@v0.2.1/base64url.d.ts +1 -0
- package/types/deps/deno.land/x/sha1@v1.0.3/deps.d.ts +1 -0
- package/types/deps/deno.land/x/sha1@v1.0.3/mod.d.ts +26 -0
- package/types/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.d.ts +3 -0
- package/types/pkg/commands/bitop.d.ts +0 -1
- package/types/pkg/commands/bitpos.d.ts +1 -1
- package/types/pkg/commands/command.d.ts +5 -5
- package/types/pkg/commands/getdel.d.ts +7 -0
- package/types/pkg/commands/hdel.d.ts +1 -1
- package/types/pkg/commands/hrandfield.d.ts +9 -0
- package/types/pkg/commands/json_arrappend.d.ts +7 -0
- package/types/pkg/commands/json_arrindex.d.ts +13 -0
- package/types/pkg/commands/json_arrinsert.d.ts +7 -0
- package/types/pkg/commands/json_arrlen.d.ts +7 -0
- package/types/pkg/commands/json_arrpop.d.ts +7 -0
- package/types/pkg/commands/json_arrtrim.d.ts +7 -0
- package/types/pkg/commands/json_clear.d.ts +7 -0
- package/types/pkg/commands/json_del.d.ts +7 -0
- package/types/pkg/commands/json_forget.d.ts +7 -0
- package/types/pkg/commands/json_get.d.ts +15 -0
- package/types/pkg/commands/json_mget.d.ts +7 -0
- package/types/pkg/commands/json_numincrby.d.ts +7 -0
- package/types/pkg/commands/json_nummultby.d.ts +7 -0
- package/types/pkg/commands/json_objkeys.d.ts +7 -0
- package/types/pkg/commands/json_objlen.d.ts +7 -0
- package/types/pkg/commands/json_resp.d.ts +7 -0
- package/types/pkg/commands/json_set.d.ts +18 -0
- package/types/pkg/commands/json_strappend.d.ts +7 -0
- package/types/pkg/commands/json_strlen.d.ts +7 -0
- package/types/pkg/commands/json_toggle.d.ts +7 -0
- package/types/pkg/commands/json_type.d.ts +7 -0
- package/types/pkg/commands/lmove.d.ts +12 -0
- package/types/pkg/commands/lpop.d.ts +1 -1
- package/types/pkg/commands/lpos.d.ts +15 -0
- package/types/pkg/commands/mget.d.ts +1 -1
- package/types/pkg/commands/mod.d.ts +28 -0
- package/types/pkg/commands/rpop.d.ts +2 -2
- package/types/pkg/commands/scan.d.ts +2 -1
- package/types/pkg/commands/script_flush.d.ts +1 -1
- package/types/pkg/commands/sdiffstore.d.ts +1 -1
- package/types/pkg/commands/set.d.ts +31 -2
- package/types/pkg/commands/smembers.d.ts +2 -2
- package/types/pkg/commands/smismember.d.ts +7 -0
- package/types/pkg/commands/spop.d.ts +2 -2
- package/types/pkg/commands/type.d.ts +1 -1
- package/types/pkg/commands/xadd.d.ts +31 -0
- package/types/pkg/commands/xrange.d.ts +9 -0
- package/types/pkg/commands/zadd.d.ts +4 -4
- package/types/pkg/commands/zdiffstore.d.ts +7 -0
- package/types/pkg/commands/zinterstore.d.ts +1 -1
- package/types/pkg/commands/zmscore.d.ts +7 -0
- package/types/pkg/commands/zrange.d.ts +8 -1
- package/types/pkg/commands/zunionstore.d.ts +1 -1
- package/types/pkg/http.d.ts +48 -7
- package/types/pkg/pipeline.d.ts +262 -124
- package/types/pkg/redis.d.ts +187 -19
- package/types/pkg/script.d.ts +42 -0
- package/types/pkg/types.d.ts +27 -1
- package/types/platforms/cloudflare.d.ts +9 -8
- package/types/platforms/fastly.d.ts +3 -7
- package/types/platforms/node_with_fetch.d.ts +3 -22
- package/types/platforms/nodejs.d.ts +4 -7
- package/types/version.d.ts +1 -0
package/README.md
CHANGED
|
@@ -23,29 +23,11 @@ See
|
|
|
23
23
|
[the list of APIs](https://docs.upstash.com/features/restapi#rest---redis-api-compatibility)
|
|
24
24
|
supported.
|
|
25
25
|
|
|
26
|
-
## Upgrading to v1.4.0 **(ReferenceError: fetch is not defined)**
|
|
27
|
-
|
|
28
|
-
If you are running on nodejs v17 and earlier, `fetch` will not be natively
|
|
29
|
-
supported. Platforms like Vercel, Netlify, Deno, Fastly etc. provide a polyfill
|
|
30
|
-
for you. But if you are running on bare node, you need to either specify a
|
|
31
|
-
polyfill yourself or change the import path to:
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
import { Redis } from "@upstash/redis/with-fetch";
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Upgrading from v0.2.0?
|
|
38
|
-
|
|
39
|
-
Please read the
|
|
40
|
-
[migration guide](https://github.com/upstash/upstash-redis#migrating-to-v1). For
|
|
41
|
-
further explanation we wrote a
|
|
42
|
-
[blog post](https://blog.upstash.com/upstash-redis-sdk-v1).
|
|
43
|
-
|
|
44
26
|
## Quick Start
|
|
45
27
|
|
|
46
28
|
### Install
|
|
47
29
|
|
|
48
|
-
####
|
|
30
|
+
#### Node.js
|
|
49
31
|
|
|
50
32
|
```bash
|
|
51
33
|
npm install @upstash/redis
|
|
@@ -61,133 +43,7 @@ import { Redis } from "https://deno.land/x/upstash_redis/mod.ts";
|
|
|
61
43
|
|
|
62
44
|
Create a new redis database on [upstash](https://console.upstash.com/)
|
|
63
45
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
We support various platforms, such as nodejs, cloudflare and fastly. Platforms
|
|
67
|
-
differ slightly when it comes to environment variables and their `fetch` api.
|
|
68
|
-
Please use the correct import when deploying to special platforms.
|
|
69
|
-
|
|
70
|
-
#### Node.js
|
|
71
|
-
|
|
72
|
-
Examples: Vercel, Netlify, AWS Lambda
|
|
73
|
-
|
|
74
|
-
If you are running on nodejs you can set `UPSTASH_REDIS_REST_URL` and
|
|
75
|
-
`UPSTASH_REDIS_REST_TOKEN` as environment variable and create a redis instance
|
|
76
|
-
like this:
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
import { Redis } from "@upstash/redis"
|
|
80
|
-
|
|
81
|
-
const redis = new Redis({
|
|
82
|
-
url: <UPSTASH_REDIS_REST_URL>,
|
|
83
|
-
token: <UPSTASH_REDIS_REST_TOKEN>,
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
// or load directly from env
|
|
87
|
-
const redis = Redis.fromEnv()
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
If you are running on nodejs v17 and earlier, `fetch` will not be natively
|
|
91
|
-
supported. Platforms like Vercel, Netlify, Deno, Fastly etc. provide a polyfill
|
|
92
|
-
for you. But if you are running on bare node, you need to either specify a
|
|
93
|
-
polyfill yourself or change the import path to:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
import { Redis } from "@upstash/redis/with-fetch";
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
- [Code example](https://github.com/upstash/upstash-redis/blob/main/examples/nodejs)
|
|
100
|
-
|
|
101
|
-
#### Cloudflare Workers
|
|
102
|
-
|
|
103
|
-
Cloudflare handles environment variables differently than nodejs. Please add
|
|
104
|
-
`UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` using
|
|
105
|
-
`wrangler secret put ...` or in the cloudflare dashboard.
|
|
106
|
-
|
|
107
|
-
Afterwards you can create a redis instance:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { Redis } from "@upstash/redis/cloudflare"
|
|
111
|
-
|
|
112
|
-
const redis = new Redis({
|
|
113
|
-
url: <UPSTASH_REDIS_REST_URL>,
|
|
114
|
-
token: <UPSTASH_REDIS_REST_TOKEN>,
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// or load directly from global env
|
|
119
|
-
|
|
120
|
-
// service worker
|
|
121
|
-
const redis = Redis.fromEnv()
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// module worker
|
|
125
|
-
export default {
|
|
126
|
-
async fetch(request: Request, env: Bindings) {
|
|
127
|
-
const redis = Redis.fromEnv(env)
|
|
128
|
-
// ...
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
- [Code example Wrangler 2](https://github.com/upstash/upstash-redis/tree/main/examples/cloudflare-workers)
|
|
134
|
-
- [Code example Wrangler 1](https://github.com/upstash/upstash-redis/tree/main/examples/cloudflare-workers-with-wrangler-1)
|
|
135
|
-
- [Documentation](https://docs.upstash.com/redis/tutorials/cloudflare_workers_with_redis)
|
|
136
|
-
|
|
137
|
-
#### Fastly
|
|
138
|
-
|
|
139
|
-
Fastly introduces a concept called
|
|
140
|
-
[backend](https://developer.fastly.com/reference/api/services/backend/). You
|
|
141
|
-
need to configure a backend in your `fastly.toml`. An example can be found
|
|
142
|
-
[here](https://github.com/upstash/upstash-redis/blob/main/examples/fastly/fastly.toml).
|
|
143
|
-
Until the fastly api stabilizes we recommend creating an instance manually:
|
|
144
|
-
|
|
145
|
-
```ts
|
|
146
|
-
import { Redis } from "@upstash/redis/fastly"
|
|
147
|
-
|
|
148
|
-
const redis = new Redis({
|
|
149
|
-
url: <UPSTASH_REDIS_REST_URL>,
|
|
150
|
-
token: <UPSTASH_REDIS_REST_TOKEN>,
|
|
151
|
-
backend: <BACKEND_NAME>,
|
|
152
|
-
})
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
- [Code example](https://github.com/upstash/upstash-redis/tree/main/examples/fastly)
|
|
156
|
-
- [Documentation](https://blog.upstash.com/fastly-compute-edge-with-redi)
|
|
157
|
-
|
|
158
|
-
#### Deno
|
|
159
|
-
|
|
160
|
-
Examples: [Deno Deploy](https://deno.com/deploy),
|
|
161
|
-
[Netlify Edge](https://www.netlify.com/products/edge/)
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
import { Redis } from "https://deno.land/x/upstash_redis/mod.ts"
|
|
165
|
-
|
|
166
|
-
const redis = new Redis({
|
|
167
|
-
url: <UPSTASH_REDIS_REST_URL>,
|
|
168
|
-
token: <UPSTASH_REDIS_REST_TOKEN>,
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
// or
|
|
172
|
-
const redis = Redis.fromEnv();
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Working with types
|
|
176
|
-
|
|
177
|
-
Most commands allow you to provide a type to make working with typescript
|
|
178
|
-
easier.
|
|
179
|
-
|
|
180
|
-
```ts
|
|
181
|
-
const data = await redis.get<MyCustomType>("key");
|
|
182
|
-
// data is typed as `MyCustomType`
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Migrating to v1
|
|
186
|
-
|
|
187
|
-
### Explicit authentication
|
|
188
|
-
|
|
189
|
-
The library is no longer automatically trying to load connection secrets from
|
|
190
|
-
environment variables. You must either supply them yourself:
|
|
46
|
+
## Basic Usage:
|
|
191
47
|
|
|
192
48
|
```ts
|
|
193
49
|
import { Redis } from "@upstash/redis"
|
|
@@ -196,146 +52,41 @@ const redis = new Redis({
|
|
|
196
52
|
url: <UPSTASH_REDIS_REST_URL>,
|
|
197
53
|
token: <UPSTASH_REDIS_REST_TOKEN>,
|
|
198
54
|
})
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Or use one of the static constructors to load from environment variables:
|
|
202
|
-
|
|
203
|
-
```ts
|
|
204
|
-
// Nodejs
|
|
205
|
-
import { Redis } from "@upstash/redis";
|
|
206
|
-
const redis = Redis.fromEnv();
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
```ts
|
|
210
|
-
// or when deploying to cloudflare workers
|
|
211
|
-
import { Redis } from "@upstash/redis/cloudflare";
|
|
212
|
-
const redis = Redis.fromEnv();
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Error handling
|
|
216
|
-
|
|
217
|
-
Errors are now thrown automatically instead of being returned to you.
|
|
218
|
-
|
|
219
|
-
```ts
|
|
220
|
-
// old
|
|
221
|
-
const { data, error } = await set("key", "value");
|
|
222
|
-
if (error) {
|
|
223
|
-
throw new Error(error);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// new
|
|
227
|
-
const data = await redis.set("key", "value"); // error is thrown automatically
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Pipeline
|
|
231
|
-
|
|
232
|
-
`v1.0.0` introduces redis pipelines. Pipelining commands allows you to send a
|
|
233
|
-
single http request with multiple commands.
|
|
234
|
-
|
|
235
|
-
```ts
|
|
236
|
-
import { Redis } from "@upstash/redis";
|
|
237
|
-
|
|
238
|
-
const redis = new Redis({
|
|
239
|
-
/* auth */
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const p = redis.pipeline();
|
|
243
|
-
|
|
244
|
-
// Now you can chain multiple commands to create your pipeline:
|
|
245
|
-
|
|
246
|
-
p.set("key", 2);
|
|
247
|
-
p.incr("key");
|
|
248
|
-
|
|
249
|
-
// or inline:
|
|
250
|
-
p.hset("key2", "field", { hello: "world" }).hvals("key2");
|
|
251
|
-
|
|
252
|
-
// Execute the pipeline once you are done building it:
|
|
253
|
-
// `exec` returns an array where each element represents the response of a command in the pipeline.
|
|
254
|
-
// You can optionally provide a type like this to get a typed response.
|
|
255
|
-
const res = await p.exec<[Type1, Type2, Type3]>();
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
For more information about pipelines using REST see
|
|
259
|
-
[here](https://blog.upstash.com/pipeline).
|
|
260
|
-
|
|
261
|
-
### Advanced
|
|
262
|
-
|
|
263
|
-
A low level `Command` class can be imported from `@upstash/redis` in case you
|
|
264
|
-
need more control about types and or (de)serialization.
|
|
265
|
-
|
|
266
|
-
By default all objects you are storing in redis are serialized using
|
|
267
|
-
`JSON.stringify` and recursively deserialized as well. Here's an example how you
|
|
268
|
-
could customize that behaviour. Keep in mind that you need to provide a `fetch`
|
|
269
|
-
polyfill if you are running on nodejs. We recommend
|
|
270
|
-
[isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch).
|
|
271
|
-
|
|
272
|
-
```ts
|
|
273
|
-
import { Command } from "@upstash/redis/commands"
|
|
274
|
-
import { HttpClient } from "@upstash/redis/http"
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* TData represents what the user will enter or receive,
|
|
278
|
-
* TResult is the raw data returned from upstash, which may need to be
|
|
279
|
-
* transformed or parsed.
|
|
280
|
-
*/
|
|
281
|
-
const deserialize: (raw: TResult) => TData = ...
|
|
282
|
-
|
|
283
|
-
class CustomGetCommand<TData, TResult> extends Command<TData | null, TResult | null> {
|
|
284
|
-
constructor(key: string, ) {
|
|
285
|
-
super(["get", key], { deserialize })
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const client = new HttpClient({
|
|
290
|
-
baseUrl: <UPSTASH_REDIS_REST_URL>,
|
|
291
|
-
headers: {
|
|
292
|
-
authorization: `Bearer ${<UPSTASH_REDIS_REST_TOKEN>}`,
|
|
293
|
-
},
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
const res = new CustomGetCommand("key").exec(client)
|
|
297
|
-
```
|
|
298
55
|
|
|
299
|
-
|
|
56
|
+
// string
|
|
57
|
+
await redis.set('key', 'value');
|
|
58
|
+
let data = await redis.get('key');
|
|
59
|
+
console.log(data)
|
|
300
60
|
|
|
301
|
-
|
|
61
|
+
await redis.set('key2', 'value2', {ex: 1});
|
|
302
62
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
63
|
+
// sorted set
|
|
64
|
+
await redis.zadd('scores', { score: 1, member: 'team1' })
|
|
65
|
+
data = await redis.zrange('scores', 0, 100 )
|
|
66
|
+
console.log(data)
|
|
307
67
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
68
|
+
// list
|
|
69
|
+
await redis.lpush('elements', 'magnesium')
|
|
70
|
+
data = await redis.lrange('elements', 0, 100 )
|
|
71
|
+
console.log(data)
|
|
312
72
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
73
|
+
// hash
|
|
74
|
+
await redis.hset('people', {name: 'joe'})
|
|
75
|
+
data = await redis.hget('people', 'name' )
|
|
76
|
+
console.log(data)
|
|
316
77
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
78
|
+
// sets
|
|
79
|
+
await redis.sadd('animals', 'cat')
|
|
80
|
+
data = await redis.spop('animals', 1)
|
|
81
|
+
console.log(data)
|
|
320
82
|
```
|
|
321
83
|
|
|
322
|
-
|
|
323
|
-
initialized and the previously established connection to upstash is reused.
|
|
84
|
+
## Troubleshooting
|
|
324
85
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
deserializer will return them as string instead. This might cause a mismatch
|
|
330
|
-
with your custom types.
|
|
331
|
-
|
|
332
|
-
```ts
|
|
333
|
-
await redis.set("key", "101600000000150081467");
|
|
334
|
-
const res = await redis<number>("get");
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
In this example `res` will still be a string despite the type annotation. Please
|
|
338
|
-
keep that in mind and adjust accordingly.
|
|
86
|
+
We have a
|
|
87
|
+
[dedicated page](https://docs.upstash.com/redis/sdks/javascriptsdk/troubleshooting)
|
|
88
|
+
for common problems. If you can't find a solution, please
|
|
89
|
+
[open an issue](https://github.com/upstash/upstash-redis/issues/new).
|
|
339
90
|
|
|
340
91
|
## Docs
|
|
341
92
|
|
|
@@ -357,5 +108,18 @@ the url and token
|
|
|
357
108
|
UPSTASH_REDIS_REST_URL=".." UPSTASH_REDIS_REST_TOKEN=".." deno test -A
|
|
358
109
|
```
|
|
359
110
|
|
|
360
|
-
|
|
111
|
+
### Telemetry
|
|
112
|
+
|
|
113
|
+
This library sends anonymous telemetry data to help us improve your experience.
|
|
114
|
+
We collect the following:
|
|
115
|
+
|
|
116
|
+
- SDK version
|
|
117
|
+
- Platform (Deno, Cloudflare, Vercel)
|
|
118
|
+
- Runtime version (node@18.x)
|
|
119
|
+
|
|
120
|
+
You can opt out by setting the `UPSTASH_DISABLE_TELEMETRY` environment variable
|
|
121
|
+
to any truthy value.
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
UPSTASH_DISABLE_TELEMETRY=1
|
|
361
125
|
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
function getLengths(b64) {
|
|
2
|
+
const len = b64.length;
|
|
3
|
+
// if (len % 4 > 0) {
|
|
4
|
+
// throw new TypeError("Invalid string. Length must be a multiple of 4");
|
|
5
|
+
// }
|
|
6
|
+
// Trim off extra bytes after placeholder bytes are found
|
|
7
|
+
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
8
|
+
let validLen = b64.indexOf("=");
|
|
9
|
+
if (validLen === -1) {
|
|
10
|
+
validLen = len;
|
|
11
|
+
}
|
|
12
|
+
const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
|
|
13
|
+
return [validLen, placeHoldersLen];
|
|
14
|
+
}
|
|
15
|
+
export function init(lookup, revLookup, urlsafe = false) {
|
|
16
|
+
function _byteLength(validLen, placeHoldersLen) {
|
|
17
|
+
return Math.floor(((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen);
|
|
18
|
+
}
|
|
19
|
+
function tripletToBase64(num) {
|
|
20
|
+
return (lookup[(num >> 18) & 0x3f] +
|
|
21
|
+
lookup[(num >> 12) & 0x3f] +
|
|
22
|
+
lookup[(num >> 6) & 0x3f] +
|
|
23
|
+
lookup[num & 0x3f]);
|
|
24
|
+
}
|
|
25
|
+
function encodeChunk(buf, start, end) {
|
|
26
|
+
const out = new Array((end - start) / 3);
|
|
27
|
+
for (let i = start, curTriplet = 0; i < end; i += 3) {
|
|
28
|
+
out[curTriplet++] = tripletToBase64((buf[i] << 16) + (buf[i + 1] << 8) + buf[i + 2]);
|
|
29
|
+
}
|
|
30
|
+
return out.join("");
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
// base64 is 4/3 + up to two characters of the original data
|
|
34
|
+
byteLength(b64) {
|
|
35
|
+
return _byteLength.apply(null, getLengths(b64));
|
|
36
|
+
},
|
|
37
|
+
toUint8Array(b64) {
|
|
38
|
+
const [validLen, placeHoldersLen] = getLengths(b64);
|
|
39
|
+
const buf = new Uint8Array(_byteLength(validLen, placeHoldersLen));
|
|
40
|
+
// If there are placeholders, only get up to the last complete 4 chars
|
|
41
|
+
const len = placeHoldersLen ? validLen - 4 : validLen;
|
|
42
|
+
let tmp;
|
|
43
|
+
let curByte = 0;
|
|
44
|
+
let i;
|
|
45
|
+
for (i = 0; i < len; i += 4) {
|
|
46
|
+
tmp = (revLookup[b64.charCodeAt(i)] << 18) |
|
|
47
|
+
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
|
48
|
+
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
|
49
|
+
revLookup[b64.charCodeAt(i + 3)];
|
|
50
|
+
buf[curByte++] = (tmp >> 16) & 0xff;
|
|
51
|
+
buf[curByte++] = (tmp >> 8) & 0xff;
|
|
52
|
+
buf[curByte++] = tmp & 0xff;
|
|
53
|
+
}
|
|
54
|
+
if (placeHoldersLen === 2) {
|
|
55
|
+
tmp = (revLookup[b64.charCodeAt(i)] << 2) |
|
|
56
|
+
(revLookup[b64.charCodeAt(i + 1)] >> 4);
|
|
57
|
+
buf[curByte++] = tmp & 0xff;
|
|
58
|
+
}
|
|
59
|
+
else if (placeHoldersLen === 1) {
|
|
60
|
+
tmp = (revLookup[b64.charCodeAt(i)] << 10) |
|
|
61
|
+
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
|
62
|
+
(revLookup[b64.charCodeAt(i + 2)] >> 2);
|
|
63
|
+
buf[curByte++] = (tmp >> 8) & 0xff;
|
|
64
|
+
buf[curByte++] = tmp & 0xff;
|
|
65
|
+
}
|
|
66
|
+
return buf;
|
|
67
|
+
},
|
|
68
|
+
fromUint8Array(buf) {
|
|
69
|
+
const maxChunkLength = 16383; // Must be multiple of 3
|
|
70
|
+
const len = buf.length;
|
|
71
|
+
const extraBytes = len % 3; // If we have 1 byte left, pad 2 bytes
|
|
72
|
+
const len2 = len - extraBytes;
|
|
73
|
+
const parts = new Array(Math.ceil(len2 / maxChunkLength) + (extraBytes ? 1 : 0));
|
|
74
|
+
let curChunk = 0;
|
|
75
|
+
let chunkEnd;
|
|
76
|
+
// Go through the array every three bytes, we'll deal with trailing stuff later
|
|
77
|
+
for (let i = 0; i < len2; i += maxChunkLength) {
|
|
78
|
+
chunkEnd = i + maxChunkLength;
|
|
79
|
+
parts[curChunk++] = encodeChunk(buf, i, chunkEnd > len2 ? len2 : chunkEnd);
|
|
80
|
+
}
|
|
81
|
+
let tmp;
|
|
82
|
+
// Pad the end with zeros, but make sure to not forget the extra bytes
|
|
83
|
+
if (extraBytes === 1) {
|
|
84
|
+
tmp = buf[len2];
|
|
85
|
+
parts[curChunk] = lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f];
|
|
86
|
+
if (!urlsafe)
|
|
87
|
+
parts[curChunk] += "==";
|
|
88
|
+
}
|
|
89
|
+
else if (extraBytes === 2) {
|
|
90
|
+
tmp = (buf[len2] << 8) | (buf[len2 + 1] & 0xff);
|
|
91
|
+
parts[curChunk] = lookup[tmp >> 10] +
|
|
92
|
+
lookup[(tmp >> 4) & 0x3f] +
|
|
93
|
+
lookup[(tmp << 2) & 0x3f];
|
|
94
|
+
if (!urlsafe)
|
|
95
|
+
parts[curChunk] += "=";
|
|
96
|
+
}
|
|
97
|
+
return parts.join("");
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { init } from "./base.js";
|
|
2
|
+
const lookup = [];
|
|
3
|
+
const revLookup = [];
|
|
4
|
+
const code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
5
|
+
for (let i = 0, l = code.length; i < l; ++i) {
|
|
6
|
+
lookup[i] = code[i];
|
|
7
|
+
revLookup[code.charCodeAt(i)] = i;
|
|
8
|
+
}
|
|
9
|
+
export const { byteLength, toUint8Array, fromUint8Array } = init(lookup, revLookup, true);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { encode, decode } from "../../../denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.js";
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { encode, decode } from "./deps.js";
|
|
2
|
+
function rotl(x, n) {
|
|
3
|
+
return (x << n) | (x >>> (32 - n));
|
|
4
|
+
}
|
|
5
|
+
/** Byte length of a SHA1 digest. */
|
|
6
|
+
export const BYTES = 20;
|
|
7
|
+
/** A class representation of the SHA1 algorithm. */
|
|
8
|
+
export class SHA1 {
|
|
9
|
+
/** Creates a SHA1 instance. */
|
|
10
|
+
constructor() {
|
|
11
|
+
Object.defineProperty(this, "hashSize", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: BYTES
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(this, "_buf", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: new Uint8Array(64)
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "_bufIdx", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "_count", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "_K", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: new Uint32Array([0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6])
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "_H", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(this, "_finalized", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: void 0
|
|
52
|
+
});
|
|
53
|
+
this.init();
|
|
54
|
+
}
|
|
55
|
+
/** Reduces the four input numbers to a single one. */
|
|
56
|
+
static F(t, b, c, d) {
|
|
57
|
+
if (t <= 19) {
|
|
58
|
+
return (b & c) | (~b & d);
|
|
59
|
+
}
|
|
60
|
+
else if (t <= 39) {
|
|
61
|
+
return b ^ c ^ d;
|
|
62
|
+
}
|
|
63
|
+
else if (t <= 59) {
|
|
64
|
+
return (b & c) | (b & d) | (c & d);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return b ^ c ^ d;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Initializes a hash instance. */
|
|
71
|
+
init() {
|
|
72
|
+
// prettier-ignore
|
|
73
|
+
this._H = new Uint32Array([
|
|
74
|
+
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
|
|
75
|
+
]);
|
|
76
|
+
this._bufIdx = 0;
|
|
77
|
+
this._count = new Uint32Array(2);
|
|
78
|
+
this._buf.fill(0);
|
|
79
|
+
this._finalized = false;
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
/** Updates a hash with additional message data. */
|
|
83
|
+
update(msg, inputEncoding) {
|
|
84
|
+
if (msg === null) {
|
|
85
|
+
throw new TypeError("msg must be a string or Uint8Array.");
|
|
86
|
+
}
|
|
87
|
+
else if (typeof msg === "string") {
|
|
88
|
+
msg = encode(msg, inputEncoding);
|
|
89
|
+
}
|
|
90
|
+
// process the msg as many times as possible, the rest is stored in the buffer
|
|
91
|
+
// message is processed in 512 bit (64 byte chunks)
|
|
92
|
+
for (let i = 0; i < msg.length; i++) {
|
|
93
|
+
this._buf[this._bufIdx++] = msg[i];
|
|
94
|
+
if (this._bufIdx === 64) {
|
|
95
|
+
this.transform();
|
|
96
|
+
this._bufIdx = 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// counter update (number of message bits)
|
|
100
|
+
const c = this._count;
|
|
101
|
+
if ((c[0] += msg.length << 3) < msg.length << 3) {
|
|
102
|
+
c[1]++;
|
|
103
|
+
}
|
|
104
|
+
c[1] += msg.length >>> 29;
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
/** Finalizes a hash with additional message data. */
|
|
108
|
+
digest(outputEncoding) {
|
|
109
|
+
if (this._finalized) {
|
|
110
|
+
throw new Error("digest has already been called.");
|
|
111
|
+
}
|
|
112
|
+
this._finalized = true;
|
|
113
|
+
// append '1'
|
|
114
|
+
const b = this._buf;
|
|
115
|
+
let idx = this._bufIdx;
|
|
116
|
+
b[idx++] = 0x80;
|
|
117
|
+
// zeropad up to byte pos 56
|
|
118
|
+
while (idx !== 56) {
|
|
119
|
+
if (idx === 64) {
|
|
120
|
+
this.transform();
|
|
121
|
+
idx = 0;
|
|
122
|
+
}
|
|
123
|
+
b[idx++] = 0;
|
|
124
|
+
}
|
|
125
|
+
// append length in bits
|
|
126
|
+
const c = this._count;
|
|
127
|
+
b[56] = (c[1] >>> 24) & 0xff;
|
|
128
|
+
b[57] = (c[1] >>> 16) & 0xff;
|
|
129
|
+
b[58] = (c[1] >>> 8) & 0xff;
|
|
130
|
+
b[59] = (c[1] >>> 0) & 0xff;
|
|
131
|
+
b[60] = (c[0] >>> 24) & 0xff;
|
|
132
|
+
b[61] = (c[0] >>> 16) & 0xff;
|
|
133
|
+
b[62] = (c[0] >>> 8) & 0xff;
|
|
134
|
+
b[63] = (c[0] >>> 0) & 0xff;
|
|
135
|
+
this.transform();
|
|
136
|
+
// return the hash as byte array (20 bytes)
|
|
137
|
+
const hash = new Uint8Array(BYTES);
|
|
138
|
+
for (let i = 0; i < 5; i++) {
|
|
139
|
+
hash[(i << 2) + 0] = (this._H[i] >>> 24) & 0xff;
|
|
140
|
+
hash[(i << 2) + 1] = (this._H[i] >>> 16) & 0xff;
|
|
141
|
+
hash[(i << 2) + 2] = (this._H[i] >>> 8) & 0xff;
|
|
142
|
+
hash[(i << 2) + 3] = (this._H[i] >>> 0) & 0xff;
|
|
143
|
+
}
|
|
144
|
+
// clear internal states and prepare for new hash
|
|
145
|
+
this.init();
|
|
146
|
+
return outputEncoding ? decode(hash, outputEncoding) : hash;
|
|
147
|
+
}
|
|
148
|
+
/** Performs one transformation cycle. */
|
|
149
|
+
transform() {
|
|
150
|
+
const h = this._H;
|
|
151
|
+
let a = h[0];
|
|
152
|
+
let b = h[1];
|
|
153
|
+
let c = h[2];
|
|
154
|
+
let d = h[3];
|
|
155
|
+
let e = h[4];
|
|
156
|
+
// convert byte buffer to words
|
|
157
|
+
const w = new Uint32Array(80);
|
|
158
|
+
for (let i = 0; i < 16; i++) {
|
|
159
|
+
w[i] =
|
|
160
|
+
this._buf[(i << 2) + 3] |
|
|
161
|
+
(this._buf[(i << 2) + 2] << 8) |
|
|
162
|
+
(this._buf[(i << 2) + 1] << 16) |
|
|
163
|
+
(this._buf[i << 2] << 24);
|
|
164
|
+
}
|
|
165
|
+
for (let t = 0; t < 80; t++) {
|
|
166
|
+
if (t >= 16) {
|
|
167
|
+
w[t] = rotl(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
|
|
168
|
+
}
|
|
169
|
+
const tmp = (rotl(a, 5) +
|
|
170
|
+
SHA1.F(t, b, c, d) +
|
|
171
|
+
e +
|
|
172
|
+
w[t] +
|
|
173
|
+
this._K[Math.floor(t / 20)]) |
|
|
174
|
+
0;
|
|
175
|
+
e = d;
|
|
176
|
+
d = c;
|
|
177
|
+
c = rotl(b, 30);
|
|
178
|
+
b = a;
|
|
179
|
+
a = tmp;
|
|
180
|
+
}
|
|
181
|
+
h[0] = (h[0] + a) | 0;
|
|
182
|
+
h[1] = (h[1] + b) | 0;
|
|
183
|
+
h[2] = (h[2] + c) | 0;
|
|
184
|
+
h[3] = (h[3] + d) | 0;
|
|
185
|
+
h[4] = (h[4] + e) | 0;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Generates a SHA1 hash of the input data. */
|
|
189
|
+
export function sha1(msg, inputEncoding, outputEncoding) {
|
|
190
|
+
return new SHA1().update(msg, inputEncoding).digest(outputEncoding);
|
|
191
|
+
}
|