From 3cd6065ab896fc080d7899de845fdaaff5765c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jozef=20Steinh=C3=BCbl?= Date: Sat, 14 Dec 2024 21:51:14 +0100 Subject: [PATCH] feat(redis api client): improve --- bun.lockb | Bin 0 -> 6193 bytes packages/redis-api-client/bun.lockb | Bin 0 -> 10876 bytes packages/redis-api-client/package.json | 3 + packages/redis-api-client/src/index.ts | 204 ++++++++++++++++--------- 4 files changed, 137 insertions(+), 70 deletions(-) create mode 100755 bun.lockb create mode 100755 packages/redis-api-client/bun.lockb diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..380e9bd7f0bb12196e9cab65c9fb9c9d944bd564 GIT binary patch literal 6193 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 I{pbDvC$S=!K>z>% literal 0 HcmV?d00001 diff --git a/packages/redis-api-client/package.json b/packages/redis-api-client/package.json index 9e65dab..8f2c11e 100644 --- a/packages/redis-api-client/package.json +++ b/packages/redis-api-client/package.json @@ -10,5 +10,8 @@ "devDependencies": { "esbuild": "^0.15.11", "typescript": "^4.8.4" + }, + "dependencies": { + "@upstash/redis": "^1.34.3" } } diff --git a/packages/redis-api-client/src/index.ts b/packages/redis-api-client/src/index.ts index 75d1b9f..47ed68d 100644 --- a/packages/redis-api-client/src/index.ts +++ b/packages/redis-api-client/src/index.ts @@ -1,72 +1,136 @@ -export class RedisAPIClient { - private apiKey: string; - private host: string; +interface RedisClient { + connect(): Promise | void; - constructor(apiKey: string, host: string) { - this.apiKey = apiKey; - this.host = host; - } - - public async get(key: string): Promise { - const url = `${this.host}/get?key=${key}`; - const response = await fetch(url, { - headers: { - Authorization: this.apiKey, - }, - }); - - const text = await response.text(); - return text === "null" ? null : text; - } - - public async set(key: string, value: string): Promise { - const url = `${this.host}/set`; - const response = await fetch(url, { - method: "POST", - headers: { - Authorization: this.apiKey, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - key, - value, - }), - }); - - return response.text(); - } - - public async setex( - key: string, - value: string, - seconds: number, - ): Promise { - const url = `${this.host}/setex`; - const response = await fetch(url, { - method: "POST", - headers: { - Authorization: this.apiKey, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - key, - value, - seconds, - }), - }); - - return response.text(); - } - - public async del(key: string): Promise { - const url = `${this.host}/del?key=${key}`; - const response = await fetch(url, { - method: "DELETE", - headers: { - Authorization: this.apiKey, - }, - }); - - return response.text(); - } + get(key: string): Promise; + set(key: string, value: string): Promise; + setex(key: string, value: string, seconds: number): Promise; + del(key: string): Promise; +} + +export class Upstash implements RedisClient { + private url: string; + private token: string; + + private redis: import("@upstash/redis").Redis | undefined; + + constructor(url: string, token: string) { + this.url = url; + this.token = token; + + this.redis = undefined; + } + + public async connect() { + if (this.redis) { + return; + } + + this.redis = new (await import("@upstash/redis")).Redis({ + url: this.url, + token: this.token, + }); + } + + public async get(key: string): Promise { + await this.connect(); + + return (await this.redis?.get(key)) ?? null; + } + + public async set(key: string, value: string): Promise { + await this.connect(); + + return (await this.redis?.set(key, value)) ?? "OK"; + } + + public async setex( + key: string, + value: string, + seconds: number + ): Promise { + await this.connect(); + + return (await this.redis?.setex(key, seconds, value)) ?? "OK"; + } + + public async del(key: string): Promise { + await this.connect(); + + return (await this.redis?.del(key)) ?? 0; + } +} + +export class Raw implements RedisClient { + private apiKey: string; + private host: string; + + constructor(apiKey: string, host: string) { + this.apiKey = apiKey; + this.host = host; + } + + public connect() {} + + public async get(key: string): Promise { + const url = `${this.host}/get?key=${key}`; + const response = await fetch(url, { + headers: { + Authorization: this.apiKey, + }, + }); + + const text = await response.text(); + return text === "null" ? null : text; + } + + public async set(key: string, value: string): Promise { + const url = `${this.host}/set`; + const response = await fetch(url, { + method: "POST", + headers: { + Authorization: this.apiKey, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + key, + value, + }), + }); + + return response.text(); + } + + public async setex( + key: string, + value: string, + seconds: number + ): Promise { + const url = `${this.host}/setex`; + const response = await fetch(url, { + method: "POST", + headers: { + Authorization: this.apiKey, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + key, + value, + seconds, + }), + }); + + return response.text(); + } + + public async del(key: string): Promise { + const url = `${this.host}/del?key=${key}`; + const response = await fetch(url, { + method: "DELETE", + headers: { + Authorization: this.apiKey, + }, + }); + + return parseInt(await response.text()); + } }