diff --git a/.changeset/honky-dory-fox.md b/.changeset/honky-dory-fox.md index 02b98c3..dfe6e00 100644 --- a/.changeset/honky-dory-fox.md +++ b/.changeset/honky-dory-fox.md @@ -7,6 +7,3 @@ - `src/APL/index.ts`: added redis-apl export - `src/APL/redis-apl.ts`: created Redis APL - `src/APL/redis-apl.test.ts`: Tests for Redis APL - -### Changed -- npm run lint changed a lot of files, guess it wasn't ran in a while :) diff --git a/package-lock.json b/package-lock.json index a7823c2..a6f752f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ "license": "ISC", "dependencies": { "debug": "4.3.4", + "ioredis": "^5.3.2", "jose": "4.14.4", "raw-body": "2.5.2", - "redis": "^4.6.10", "retes": "0.33.0", "uuid": "9.0.0" }, @@ -41,6 +41,7 @@ "eslint-plugin-simple-import-sort": "^8.0.0", "graphql": "16.8.0", "husky": "^8.0.1", + "ioredis-mock": "^8.9.0", "jsdom": "^20.0.3", "lint-staged": "^13.0.3", "next": "^12.3.0", @@ -1162,6 +1163,17 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@ioredis/as-callback": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@ioredis/as-callback/-/as-callback-3.0.0.tgz", + "integrity": "sha512-Kqv1rZ3WbgOrS+hgzJ5xG5WQuhvzzSTRYvNeyPMLOAM78MHSnuKI20JeJGbpuAt//LCuP0vsexZcorqW7kWhJg==", + "dev": true + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -1534,64 +1546,6 @@ "node": ">= 8" } }, - "node_modules/@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/client": { - "version": "1.5.11", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.11.tgz", - "integrity": "sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA==", - "dependencies": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@redis/client/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/search": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.5.tgz", - "integrity": "sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, "node_modules/@swc/helpers": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz", @@ -1747,6 +1701,16 @@ "@types/ms": "*" } }, + "node_modules/@types/ioredis-mock": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/ioredis-mock/-/ioredis-mock-8.2.3.tgz", + "integrity": "sha512-7veA+v2QXjPBvmuYDSyXcfcgCzlpMxa9z51g1+bZXLZ97teCmEs9qYiK9X/h7camGAJJvTiFHiE4mT8CNaqQlA==", + "dev": true, + "peer": true, + "dependencies": { + "ioredis": ">=5" + } + }, "node_modules/@types/is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/is-ci/-/is-ci-3.0.1.tgz", @@ -3466,6 +3430,14 @@ "node": ">=0.4.0" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -4970,6 +4942,32 @@ "reusify": "^1.0.4" } }, + "node_modules/fengari": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", + "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", + "dev": true, + "dependencies": { + "readline-sync": "^1.4.9", + "sprintf-js": "^1.1.1", + "tmp": "^0.0.33" + } + }, + "node_modules/fengari-interop": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/fengari-interop/-/fengari-interop-0.1.3.tgz", + "integrity": "sha512-EtZ+oTu3kEwVJnoymFPBVLIbQcCoy9uWCVnMA6h3M/RqHkUBsLYp29+RRHf9rKr6GwjubWREU1O7RretFIXjHw==", + "dev": true, + "peerDependencies": { + "fengari": "^0.1.0" + } + }, + "node_modules/fengari/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5164,14 +5162,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "engines": { - "node": ">= 4" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -5655,6 +5645,49 @@ "node": ">= 0.4" } }, + "node_modules/ioredis": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", + "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ioredis-mock": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ioredis-mock/-/ioredis-mock-8.9.0.tgz", + "integrity": "sha512-yIglcCkI1lvhwJVoMsR51fotZVsPsSk07ecTCgRTRlicG0Vq3lke6aAaHklyjmRNRsdYAgswqC2A0bPtQK4LSw==", + "dev": true, + "dependencies": { + "@ioredis/as-callback": "^3.0.0", + "@ioredis/commands": "^1.2.0", + "fengari": "^0.1.4", + "fengari-interop": "^0.1.3", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12.22" + }, + "peerDependencies": { + "@types/ioredis-mock": "^8", + "ioredis": "^5" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -6489,6 +6522,16 @@ "node": ">=8" } }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -7898,6 +7941,15 @@ "node": ">=8.10.0" } }, + "node_modules/readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -7911,17 +7963,23 @@ "node": ">=8" } }, - "node_modules/redis": { - "version": "4.6.10", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.10.tgz", - "integrity": "sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg==", + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", "dependencies": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.11", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.6", - "@redis/search": "1.1.5", - "@redis/time-series": "1.0.5" + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, "node_modules/reflect.getprototypeof": { @@ -8673,6 +8731,11 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/package.json b/package.json index f908f0e..005fd4f 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ }, "dependencies": { "debug": "4.3.4", + "ioredis": "^5.3.2", "jose": "4.14.4", "raw-body": "2.5.2", - "redis": "^4.6.10", "retes": "0.33.0", "uuid": "9.0.0" }, @@ -56,6 +56,7 @@ "eslint-plugin-simple-import-sort": "^8.0.0", "graphql": "16.8.0", "husky": "^8.0.1", + "ioredis-mock": "^8.9.0", "jsdom": "^20.0.3", "lint-staged": "^13.0.3", "next": "^12.3.0", diff --git a/src/APL/redis-apl.test.ts b/src/APL/redis-apl.test.ts index 4748e45..b8cf179 100644 --- a/src/APL/redis-apl.test.ts +++ b/src/APL/redis-apl.test.ts @@ -1,10 +1,11 @@ import { afterEach, describe, expect, it } from "vitest"; +import Redis from "ioredis-mock" import { AuthData } from "./apl"; import { RedisAPL } from "./redis-apl"; -// Obviously, for this test to pass you need to have a docker container running redis :) -const localRedisServerUrl = new URL("redis://127.0.0.1:6379/1"); +const appApiBaseUrl = "https://localhost:4321/" +const redisClient = new Redis() const stubAuthData: AuthData = { domain: "example.com", token: "example-token", @@ -15,21 +16,20 @@ const stubAuthData: AuthData = { describe("APL", () => { afterEach(async () => { - const apl = new RedisAPL(localRedisServerUrl, stubAuthData.appId); + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); await apl.delete(stubAuthData.saleorApiUrl); }); describe("redisAPL", () => { describe("get", () => { it("Returns auth data for existing api url", async () => { - const apl = new RedisAPL(localRedisServerUrl, stubAuthData.appId); + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); await apl.set(stubAuthData); - expect(await apl.get(stubAuthData.saleorApiUrl)).toStrictEqual(stubAuthData); }); it("Returns undefined for unknown api url", async () => { - const apl = new RedisAPL(localRedisServerUrl, stubAuthData.appId); + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); expect(await apl.get("unknown-domain.example.com")).toBeUndefined(); }); @@ -37,7 +37,7 @@ describe("APL", () => { describe("set", () => { it("should save to redis and return value afterwards", async () => { - const apl = new RedisAPL(localRedisServerUrl, stubAuthData.appId); + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); await apl.set(stubAuthData); expect(await apl.get(stubAuthData.saleorApiUrl)).toStrictEqual(stubAuthData); @@ -46,11 +46,48 @@ describe("APL", () => { describe("delete", () => { it("Should delete when called with known domain", async () => { - const apl = new RedisAPL(localRedisServerUrl, stubAuthData.appId); + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); - await apl.delete("api.random.sk"); + await apl.delete(stubAuthData.saleorApiUrl); expect(await apl.get(stubAuthData.saleorApiUrl)).toBeUndefined(); }); + it("Should not delete when called with different domain", async () => { + const apl = new RedisAPL({ client: redisClient, appApiBaseUrl: appApiBaseUrl }); + const otherAppApiBaseUrl = "https://localhost:4322/" + const apl2 = new RedisAPL({ client: redisClient, appApiBaseUrl: otherAppApiBaseUrl }); + + const otherStubAuthData: AuthData = { + saleorApiUrl: "https://example.com/graphql", + token: "Another token", + domain: "example.net", + jwks: "{}", + appId: "22" + } + + await apl.set(stubAuthData) + await apl2.set(otherStubAuthData) + + /* good for debugging if something breaks :) + await redisClient.keys("*", (err, keys) => { + if (err) return console.log(err) + if (keys) { + keys.map(async (key) => { + let val = await redisClient.get(key) + console.log(`${key}:${val}`) + }) + } + }) + */ + expect(stubAuthData != otherStubAuthData).toBeTruthy() + expect(await apl.get(stubAuthData.saleorApiUrl)).toStrictEqual(stubAuthData); + expect(await apl2.get(otherStubAuthData.saleorApiUrl)).toStrictEqual(otherStubAuthData); + await apl.delete(stubAuthData.saleorApiUrl); + expect(await apl.get(stubAuthData.saleorApiUrl)).toBeUndefined(); + expect(await apl2.get(otherStubAuthData.saleorApiUrl)).toStrictEqual(otherStubAuthData); + await apl2.delete(otherStubAuthData.saleorApiUrl); + expect(await apl.get(stubAuthData.saleorApiUrl)).toBeUndefined(); + expect(await apl2.get(otherStubAuthData.saleorApiUrl)).toBeUndefined(); + }); }); }); }); diff --git a/src/APL/redis-apl.ts b/src/APL/redis-apl.ts index 187efe9..fe59719 100644 --- a/src/APL/redis-apl.ts +++ b/src/APL/redis-apl.ts @@ -1,10 +1,18 @@ -import { createClient } from "redis"; +import Redis from "ioredis"; import { APL, AplConfiguredResult, AplReadyResult, AuthData } from "./apl"; import { createAPLDebug } from "./apl-debug"; -const debug = createAPLDebug("UpstashAPL"); +const debug = createAPLDebug("RedisAPL"); +export type RedisAPLClientArgs = { + client: Redis, + appApiBaseUrl: string +} +export type RedisAPLUrlArgs = { + redisUrl: URL + appApiBaseUrl: string +} /** * Redis APL * @param redisUrl - in format redis[s]://[[username][:password]@][host][:port][/db-number], @@ -13,15 +21,42 @@ const debug = createAPLDebug("UpstashAPL"); */ export class RedisAPL implements APL { private client; - private appApiBaseUrl; - constructor(redisURL: URL, appApiBaseUrl: string) { - if (!redisURL) throw new Error("No redis url defined"); - if (!appApiBaseUrl) throw new Error("The RedisAPL requires to know the app ID beforehand"); - this.appApiBaseUrl = appApiBaseUrl; - this.client = createClient({ url: redisURL.toString() }); - debug("RedisAPL: createClient.url : %j", redisURL.toString()); + constructor(args: RedisAPLClientArgs | RedisAPLUrlArgs) { + if (!args.appApiBaseUrl) throw new Error("The RedisAPL requires to know the app api url beforehand"); + this.appApiBaseUrl = args.appApiBaseUrl; + + if (('client' in args) && args.client) { + this.client = args.client + debug("RedisAPL: created redis client"); + } + else if (('redisUrl' in args) && args.redisUrl) { + let redisUrl = args.redisUrl + let port, db; + + if (redisUrl.pathname) { + const parsed_port = parseInt(redisUrl.pathname) + db = typeof parsed_port === "number" ? parsed_port : undefined + } + if (redisUrl.port) { + const parsed_port = parseInt(redisUrl.port) + port = typeof parsed_port === "number" ? parsed_port : undefined + } + + this.client = new Redis({ + port: port, + host: redisUrl.host, + username: redisUrl.username, + password: redisUrl.password, + db: db, + lazyConnect: true + }); + debug("RedisAPL: created redis client"); + } + else { + throw new Error("RedisAPL: No redis url or client defined") + } } private prepareKey(saleorApiUrl: string) { @@ -29,34 +64,31 @@ export class RedisAPL implements APL { } async get(saleorApiUrl: string): Promise { - await this.client.connect(); try { const res = await this.client.get(this.prepareKey(saleorApiUrl)); debug("RedisAPL: get - received: %j", res); if (res) { - await this.client.disconnect(); + await this.client.quit(); return JSON.parse(res) as AuthData; } - await this.client.disconnect(); + await this.client.quit(); return undefined; } catch (e) { - await this.client.disconnect(); + await this.client.quit(); return undefined; } } async set(authData: AuthData): Promise { - await this.client.connect(); await this.client.set(this.prepareKey(authData.saleorApiUrl), JSON.stringify(authData)); debug("RedisAPL: set - set sucessfully: %j", authData); - await this.client.disconnect(); + await this.client.quit(); } async delete(saleorApiUrl: string): Promise { - await this.client.connect(); - const val = await this.client.getDel(this.prepareKey(saleorApiUrl)); + const val = await this.client.getdel(this.prepareKey(saleorApiUrl)); debug("RedisAPL: del - deleted successfuly: %j", val); - await this.client.disconnect(); + await this.client.quit(); } async getAll(): Promise { @@ -64,10 +96,14 @@ export class RedisAPL implements APL { } async isReady(): Promise { - return { ready: this.client.isReady } as AplReadyResult; + const ready = await this.client.info() ? true : false + await this.client.quit(); + return { ready: ready } as AplReadyResult; } async isConfigured(): Promise { - return { configured: this.client.isReady } as AplConfiguredResult; + const ready = await this.client.info() ? true : false + await this.client.quit(); + return { configured: ready } as AplConfiguredResult; } }