diff --git a/lib/clickhouse.js b/lib/clickhouse.js index 5f4cd63b..519899f2 100644 --- a/lib/clickhouse.js +++ b/lib/clickhouse.js @@ -34,7 +34,7 @@ function getClient() { }); if (process.env.NODE_ENV !== 'production') { - global[CLICKHOUSE] = clickhouse; + global[CLICKHOUSE] = client; } log('Clickhouse initialized'); diff --git a/lib/redis.js b/lib/redis.js index 01fef5a0..845f0a23 100644 --- a/lib/redis.js +++ b/lib/redis.js @@ -1,22 +1,14 @@ -import { createClient } from 'redis'; +import Redis from 'ioredis'; import { startOfMonth } from 'date-fns'; -import debug from 'debug'; +// import debug from 'debug'; import { getSessions, getAllWebsites } from 'queries'; import { REDIS } from 'lib/db'; -const log = debug('umami:redis'); +// const log = debug('umami:redis'); const INITIALIZED = 'redis:initialized'; -async function getClient() { - const redis = new createClient({ - url: process.env.REDIS_URL, - }); - - await redis.connect(); - - if (process.env.LOG_QUERY) { - redis.on('error', err => log(err)); - } +function getClient() { + const redis = new Redis(process.env.REDIS_URL); if (process.env.NODE_ENV !== 'production') { global[REDIS] = redis; @@ -26,11 +18,11 @@ async function getClient() { } async function stageData() { - const sessions = await getSessions([], startOfMonth(new Date()).toUTCString()); + const sessions = await getSessions([], startOfMonth(new Date())); const websites = await getAllWebsites(); const sessionUuids = sessions.map(a => { - return { key: `session:${a.session_uuid}`, value: '' }; + return { key: `session:${a.session_uuid}`, value: 1 }; }); const websiteIds = websites.map(a => { return { key: `website:${a.website_uuid}`, value: Number(a.website_id) }; @@ -50,16 +42,12 @@ async function addRedis(ids) { } // Initialization -let redis = null; +const redis = process.env.REDIS_URL && (global[REDIS] || getClient()); (async () => { - redis = process.env.REDIS_URL && (global[REDIS] || (await getClient())); - - if (redis) { - if (!(await redis.get(INITIALIZED))) { - await stageData(); - } + if (!(await redis.get(INITIALIZED))) { + await stageData(); } })(); -export default redis; +export default { client: redis, stageData }; diff --git a/lib/session.js b/lib/session.js index 6b8bd97b..0ab38f0d 100644 --- a/lib/session.js +++ b/lib/session.js @@ -30,9 +30,11 @@ export async function getSession(req) { let websiteId = null; + //console.log(await redis.stageData()); + // Check if website exists if (process.env.REDIS_URL) { - websiteId = await redis.get(`website:${website_uuid}`); + websiteId = await redis.client.get(`website:${website_uuid}`); } else { const { website_id } = await getWebsiteByUuid(website_uuid); websiteId = website_id; @@ -52,7 +54,7 @@ export async function getSession(req) { // Check if session exists if (process.env.REDIS_URL) { - sessionCreated = (await redis.get(`session:${session_uuid}`)) !== null; + sessionCreated = !!(await redis.client.get(`session:${session_uuid}`)); } else { session = await getSessionByUuid(session_uuid); sessionCreated = !!session; @@ -61,7 +63,7 @@ export async function getSession(req) { if (!sessionCreated) { try { - session = await createSession(websiteId, { + session = await createSession(BigInt(websiteId), { session_uuid, hostname, browser, diff --git a/package.json b/package.json index 7cbd5e55..343adc45 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "formik": "^2.2.9", "fs-extra": "^10.0.1", "immer": "^9.0.12", + "ioredis": "^5.2.3", "ipaddr.js": "^2.0.1", "is-ci": "^3.0.1", "is-docker": "^3.0.0", @@ -97,7 +98,6 @@ "react-tooltip": "^4.2.21", "react-use-measure": "^2.0.4", "react-window": "^1.8.6", - "redis": "^4.3.0", "request-ip": "^3.3.0", "semver": "^7.3.6", "thenby": "^1.3.4", diff --git a/queries/admin/website/createWebsite.js b/queries/admin/website/createWebsite.js index d5eaaf31..513e7479 100644 --- a/queries/admin/website/createWebsite.js +++ b/queries/admin/website/createWebsite.js @@ -14,7 +14,7 @@ export async function createWebsite(user_id, data) { }, }) .then(async res => { - if (process.env.REDIS_URL) { + if (process.env.REDIS_URL && res) { await redis.set(`website:${res.website_uuid}`, Number(res.website_id)); } diff --git a/queries/admin/website/deleteWebsite.js b/queries/admin/website/deleteWebsite.js index e09f7ebb..15667f70 100644 --- a/queries/admin/website/deleteWebsite.js +++ b/queries/admin/website/deleteWebsite.js @@ -22,7 +22,7 @@ export async function deleteWebsite(website_id) { }), ]).then(async res => { if (process.env.REDIS_URL) { - await redis.del(`website:${res.website_uuid}`); + await redis.client.del(`website:${res.website_uuid}`); } }); } diff --git a/queries/admin/website/getWebsiteByUuid.js b/queries/admin/website/getWebsiteByUuid.js index 1b9aeb4c..36db53b9 100644 --- a/queries/admin/website/getWebsiteByUuid.js +++ b/queries/admin/website/getWebsiteByUuid.js @@ -1,9 +1,18 @@ import prisma from 'lib/prisma'; +import redis from 'lib/redis'; export async function getWebsiteByUuid(website_uuid) { - return prisma.client.website.findUnique({ - where: { - website_uuid, - }, - }); + return prisma.client.website + .findUnique({ + where: { + website_uuid, + }, + }) + .then(async res => { + if (process.env.REDIS_URL && res) { + await redis.client.set(`website:${res.website_uuid}`, 1); + } + + return res; + }); } diff --git a/queries/analytics/event/saveEvent.js b/queries/analytics/event/saveEvent.js index 10e894ae..6391868c 100644 --- a/queries/analytics/event/saveEvent.js +++ b/queries/analytics/event/saveEvent.js @@ -1,14 +1,12 @@ -import prisma from 'lib/prisma'; -import clickhouse from 'lib/clickhouse'; +import { EVENT_NAME_LENGTH, URL_LENGTH } from 'lib/constants'; +import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; import kafka from 'lib/kafka'; -import { runQuery, CLICKHOUSE, KAFKA, PRISMA } from 'lib/db'; -import { URL_LENGTH, EVENT_NAME_LENGTH } from 'lib/constants'; +import prisma from 'lib/prisma'; export async function saveEvent(...args) { return runQuery({ [PRISMA]: () => relationalQuery(...args), [CLICKHOUSE]: () => clickhouseQuery(...args), - [KAFKA]: () => kafkaQuery(...args), }); } @@ -34,23 +32,6 @@ async function relationalQuery(website_id, { session_id, url, event_name, event_ } async function clickhouseQuery(website_id, { event_uuid, session_uuid, url, event_name }) { - const { rawQuery, getDateFormat } = clickhouse; - const params = [ - website_id, - event_uuid, - session_uuid, - url?.substring(0, URL_LENGTH), - event_name?.substring(0, EVENT_NAME_LENGTH), - ]; - - return rawQuery( - `insert into umami.event (created_at, website_id, session_uuid, url, event_name) - values (${getDateFormat(new Date())}, $1, $2, $3, $4);`, - params, - ); -} - -async function kafkaQuery(website_id, { event_uuid, session_uuid, url, event_name }) { const { getDateFormat, sendMessage } = kafka; const params = { event_uuid: event_uuid, diff --git a/queries/analytics/pageview/savePageView.js b/queries/analytics/pageview/savePageView.js index 36698127..3739ff43 100644 --- a/queries/analytics/pageview/savePageView.js +++ b/queries/analytics/pageview/savePageView.js @@ -1,14 +1,12 @@ -import prisma from 'lib/prisma'; -import clickhouse from 'lib/clickhouse'; -import kafka from 'lib/kafka'; -import { runQuery, CLICKHOUSE, KAFKA, PRISMA } from 'lib/db'; import { URL_LENGTH } from 'lib/constants'; +import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; +import kafka from 'lib/kafka'; +import prisma from 'lib/prisma'; export async function savePageView(...args) { return runQuery({ [PRISMA]: () => relationalQuery(...args), [CLICKHOUSE]: () => clickhouseQuery(...args), - [KAFKA]: () => kafkaQuery(...args), }); } @@ -24,21 +22,6 @@ async function relationalQuery(website_id, { session_id, url, referrer }) { } async function clickhouseQuery(website_id, { session_uuid, url, referrer }) { - const params = [ - website_id, - session_uuid, - url?.substring(0, URL_LENGTH), - referrer?.substring(0, URL_LENGTH), - ]; - - return clickhouse.rawQuery( - `insert into umami.pageview (created_at, website_id, session_uuid, url, referrer) - values (${clickhouse.getDateFormat(new Date())}, $1, $2, $3, $4);`, - params, - ); -} - -async function kafkaQuery(website_id, { session_uuid, url, referrer }) { const { getDateFormat, sendMessage } = kafka; const params = { website_id: website_id, diff --git a/queries/analytics/session/createSession.js b/queries/analytics/session/createSession.js index 994f9ef5..82753a59 100644 --- a/queries/analytics/session/createSession.js +++ b/queries/analytics/session/createSession.js @@ -1,14 +1,12 @@ -import prisma from 'lib/prisma'; -import clickhouse from 'lib/clickhouse'; +import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; import kafka from 'lib/kafka'; +import prisma from 'lib/prisma'; import redis from 'lib/redis'; -import { runQuery, CLICKHOUSE, KAFKA, PRISMA } from 'lib/db'; export async function createSession(...args) { return runQuery({ [PRISMA]: () => relationalQuery(...args), [CLICKHOUSE]: () => clickhouseQuery(...args), - [KAFKA]: () => kafkaQuery(...args), }); } @@ -24,8 +22,8 @@ async function relationalQuery(website_id, data) { }, }) .then(async res => { - if (process.env.REDIS_URL) { - await redis.set(`session:${res.session_uuid}`, ''); + if (process.env.REDIS_URL && res) { + await redis.client.set(`session:${res.session_uuid}`, 1); } return res; @@ -35,30 +33,6 @@ async function relationalQuery(website_id, data) { async function clickhouseQuery( website_id, { session_uuid, hostname, browser, os, screen, language, country, device }, -) { - const params = [ - session_uuid, - website_id, - hostname, - browser, - os, - device, - screen, - language, - country ? country : null, - ]; - const { rawQuery, getDateFormat } = clickhouse; - - await rawQuery( - `insert into umami.session (created_at, session_uuid, website_id, hostname, browser, os, device, screen, language, country) - values (${getDateFormat(new Date())}, $1, $2, $3, $4, $5, $6, $7, $8, $9);`, - params, - ); -} - -async function kafkaQuery( - website_id, - { session_uuid, hostname, browser, os, screen, language, country, device }, ) { const { getDateFormat, sendMessage } = kafka; const params = { @@ -76,5 +50,7 @@ async function kafkaQuery( await sendMessage(params, 'session'); - await redis.set(`session:${session_uuid}`, ''); + if (process.env.REDIS_URL) { + await redis.client.set(`session:${session_uuid}`, 1); + } } diff --git a/queries/analytics/session/getSessionByUuid.js b/queries/analytics/session/getSessionByUuid.js index 6e92a2ca..db564d46 100644 --- a/queries/analytics/session/getSessionByUuid.js +++ b/queries/analytics/session/getSessionByUuid.js @@ -1,6 +1,7 @@ -import prisma from 'lib/prisma'; import clickhouse from 'lib/clickhouse'; -import { runQuery, CLICKHOUSE, PRISMA } from 'lib/db'; +import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; +import prisma from 'lib/prisma'; +import redis from 'lib/redis'; export async function getSessionByUuid(...args) { return runQuery({ @@ -10,11 +11,19 @@ export async function getSessionByUuid(...args) { } async function relationalQuery(session_uuid) { - return prisma.client.session.findUnique({ - where: { - session_uuid, - }, - }); + return prisma.client.session + .findUnique({ + where: { + session_uuid, + }, + }) + .then(async res => { + if (process.env.REDIS_URL && res) { + await redis.client.set(`session:${res.session_uuid}`, 1); + } + + return res; + }); } async function clickhouseQuery(session_uuid) { @@ -36,5 +45,13 @@ async function clickhouseQuery(session_uuid) { from session where session_uuid = $1`, params, - ).then(result => findFirst(result)); + ) + .then(result => findFirst(result)) + .then(async res => { + if (process.env.REDIS_URL && res) { + await redis.client.set(`session:${res.session_uuid}`, 1); + } + + return res; + }); } diff --git a/queries/analytics/session/getSessions.js b/queries/analytics/session/getSessions.js index bf070651..36095d0e 100644 --- a/queries/analytics/session/getSessions.js +++ b/queries/analytics/session/getSessions.js @@ -10,24 +10,22 @@ export async function getSessions(...args) { } async function relationalQuery(websites, start_at) { - return runQuery( - prisma.client.session.findMany({ - where: { - ...(websites && websites.length > 0 - ? { - website: { - website_id: { - in: websites, - }, + return prisma.client.session.findMany({ + where: { + ...(websites && websites.length > 0 + ? { + website: { + website_id: { + in: websites, }, - } - : {}), - created_at: { - gte: start_at, - }, + }, + } + : {}), + created_at: { + gte: start_at, }, - }), - ); + }, + }); } async function clickhouseQuery(websites, start_at) { diff --git a/yarn.lock b/yarn.lock index 5da68afe..b14f94f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1294,6 +1294,11 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -1543,40 +1548,6 @@ "@react-spring/shared" "~9.5.2" "@react-spring/types" "~9.5.2" -"@redis/bloom@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.0.2.tgz#42b82ec399a92db05e29fffcdfd9235a5fc15cdf" - integrity sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw== - -"@redis/client@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.3.0.tgz#c62ccd707f16370a2dc2f9e158a28b7da049fa77" - integrity sha512-XCFV60nloXAefDsPnYMjHGtvbtHR8fV5Om8cQ0JYqTNbWcQo/4AryzJ2luRj4blveWazRK/j40gES8M7Cp6cfQ== - dependencies: - cluster-key-slot "1.1.0" - generic-pool "3.8.2" - yallist "4.0.0" - -"@redis/graph@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.0.1.tgz#eabc58ba99cd70d0c907169c02b55497e4ec8a99" - integrity sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ== - -"@redis/json@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.3.tgz#a13fde1d22ebff0ae2805cd8e1e70522b08ea866" - integrity sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q== - -"@redis/search@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.0.tgz#7abb18d431f27ceafe6bcb4dd83a3fa67e9ab4df" - integrity sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ== - -"@redis/time-series@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.3.tgz#4cfca8e564228c0bddcdf4418cba60c20b224ac4" - integrity sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA== - "@rollup/plugin-buble@^0.21.3": version "0.21.3" resolved "https://registry.npmjs.org/@rollup/plugin-buble/-/plugin-buble-0.21.3.tgz" @@ -2514,7 +2485,7 @@ clickhouse@^2.5.0: tsv "0.2.0" uuid "3.4.0" -cluster-key-slot@1.1.0: +cluster-key-slot@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== @@ -2946,6 +2917,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +denque@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + detect-browser@^5.2.0: version "5.3.0" resolved "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz" @@ -3631,11 +3607,6 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -generic-pool@3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.8.2.tgz#aab4f280adb522fdfbdc5e5b64d718d3683f04e9" - integrity sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg== - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -3958,6 +3929,21 @@ intl-messageformat@9.13.0: "@formatjs/icu-messageformat-parser" "2.1.0" tslib "^2.1.0" +ioredis@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.2.3.tgz#d5b37eb13e643241660d6cee4eeb41a026cda8c0" + integrity sha512-gQNcMF23/NpvjCaa1b5YycUyQJ9rBNH2xP94LWinNpodMWVUPP5Ai/xXANn/SM7gfIvI62B5CCvZxhg5pOgyMw== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.0.1" + 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" + ipaddr.js@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz" @@ -4433,11 +4419,21 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" @@ -5649,17 +5645,17 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -redis@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/redis/-/redis-4.3.0.tgz#c01de4cf13821406addb7fcb70afe203266c4c39" - integrity sha512-RXRUor0iU1vizu4viHoUyLpe1ZO/RngZp0V9DyXBHTI+7tC7rEz6Wzn4Sv9v0tTJeqGAzdJ+q5YVbNKKQ5hX9A== +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== dependencies: - "@redis/bloom" "1.0.2" - "@redis/client" "1.3.0" - "@redis/graph" "1.0.1" - "@redis/json" "1.0.3" - "@redis/search" "1.1.0" - "@redis/time-series" "1.0.3" + redis-errors "^1.0.0" redux@^4.0.0, redux@^4.0.4: version "4.2.0" @@ -6135,6 +6131,11 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + stream2asynciter@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/stream2asynciter/-/stream2asynciter-1.0.3.tgz#7ba9046846c8b1caf36ec30d64a73514f7f44c5a" @@ -6809,7 +6810,7 @@ write-json-file@^4.3.0: sort-keys "^4.0.0" write-file-atomic "^3.0.0" -yallist@4.0.0, yallist@^4.0.0: +yallist@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==