mirror of
https://github.com/kremalicious/umami.git
synced 2024-12-24 02:06:19 +01:00
Updated prisma and redis clients.
This commit is contained in:
parent
c05d116875
commit
dff105c747
14
lib/cache.ts
14
lib/cache.ts
@ -1,10 +1,16 @@
|
||||
import { User, Website } from '@prisma/client';
|
||||
import redis from 'lib/redis';
|
||||
import redis from '@umami/redis-client';
|
||||
import { getSession, getUser, getWebsite } from '../queries';
|
||||
|
||||
const DELETED = 'DELETED';
|
||||
|
||||
async function fetchObject(key, query) {
|
||||
const obj = await redis.get(key);
|
||||
|
||||
if (obj === DELETED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
return query().then(async data => {
|
||||
if (data) {
|
||||
@ -22,8 +28,8 @@ async function storeObject(key, data) {
|
||||
return redis.set(key, data);
|
||||
}
|
||||
|
||||
async function deleteObject(key) {
|
||||
return redis.set(key, redis.DELETED);
|
||||
async function deleteObject(key, soft = false) {
|
||||
return soft ? redis.set(key, DELETED) : redis.del(key);
|
||||
}
|
||||
|
||||
async function fetchWebsite(id): Promise<Website> {
|
||||
@ -42,7 +48,7 @@ async function deleteWebsite(id) {
|
||||
}
|
||||
|
||||
async function fetchUser(id): Promise<User> {
|
||||
return fetchObject(`user:${id}`, () => getUser({ id }, true));
|
||||
return fetchObject(`user:${id}`, () => getUser({ id }, { includePassword: true }));
|
||||
}
|
||||
|
||||
async function storeUser(data) {
|
||||
|
@ -4,7 +4,6 @@ export const MYSQL = 'mysql';
|
||||
export const CLICKHOUSE = 'clickhouse';
|
||||
export const KAFKA = 'kafka';
|
||||
export const KAFKA_PRODUCER = 'kafka-producer';
|
||||
export const REDIS = 'redis';
|
||||
|
||||
// Fixes issue with converting bigint values
|
||||
BigInt.prototype.toJSON = function () {
|
||||
|
@ -2,10 +2,10 @@ import { createMiddleware, unauthorized, badRequest, parseSecureToken } from 'ne
|
||||
import debug from 'debug';
|
||||
import cors from 'cors';
|
||||
import { validate } from 'uuid';
|
||||
import redis from '@umami/redis-client';
|
||||
import { findSession } from 'lib/session';
|
||||
import { getAuthToken, parseShareToken } from 'lib/auth';
|
||||
import { secret } from 'lib/crypto';
|
||||
import redis from 'lib/redis';
|
||||
import { ROLES } from 'lib/constants';
|
||||
import { getUser } from '../queries';
|
||||
|
||||
@ -17,7 +17,7 @@ export const useSession = createMiddleware(async (req, res, next) => {
|
||||
const session = await findSession(req);
|
||||
|
||||
if (!session) {
|
||||
log('useSession:session-not-found');
|
||||
log('useSession: Session not found');
|
||||
return badRequest(res);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export const useAuth = createMiddleware(async (req, res, next) => {
|
||||
log({ token, payload, user, shareToken });
|
||||
|
||||
if (!user && !shareToken) {
|
||||
log('useAuth:user-not-authorized');
|
||||
log('useAuth: User not authorized');
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import chalk from 'chalk';
|
||||
import prisma from '@umami/prisma-client';
|
||||
import moment from 'moment-timezone';
|
||||
import debug from 'debug';
|
||||
import { PRISMA, MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db';
|
||||
import { MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db';
|
||||
import { FILTER_IGNORED } from 'lib/constants';
|
||||
import { PrismaClientOptions } from '@prisma/client/runtime';
|
||||
|
||||
const MYSQL_DATE_FORMATS = {
|
||||
minute: '%Y-%m-%d %H:%i:00',
|
||||
@ -22,39 +19,7 @@ const POSTGRESQL_DATE_FORMATS = {
|
||||
year: 'YYYY-01-01',
|
||||
};
|
||||
|
||||
const log = debug('umami:prisma');
|
||||
|
||||
const PRISMA_OPTIONS = {
|
||||
log: [
|
||||
{
|
||||
emit: 'event',
|
||||
level: 'query',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function logQuery(e) {
|
||||
log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`));
|
||||
}
|
||||
|
||||
function getClient(options) {
|
||||
const prisma: PrismaClient<PrismaClientOptions, 'query' | 'error' | 'info' | 'warn'> =
|
||||
new PrismaClient(options);
|
||||
|
||||
if (process.env.LOG_QUERY) {
|
||||
prisma.$on('query', logQuery);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
global[PRISMA] = prisma;
|
||||
}
|
||||
|
||||
log('Prisma initialized');
|
||||
|
||||
return prisma;
|
||||
}
|
||||
|
||||
function getDateQuery(field, unit, timezone?): string {
|
||||
function getDateQuery(field: string, unit: string, timezone?: string): string {
|
||||
const db = getDatabaseType(process.env.DATABASE_URL);
|
||||
|
||||
if (db === POSTGRESQL) {
|
||||
@ -75,7 +40,7 @@ function getDateQuery(field, unit, timezone?): string {
|
||||
}
|
||||
}
|
||||
|
||||
function getTimestampInterval(field): string {
|
||||
function getTimestampInterval(field: string): string {
|
||||
const db = getDatabaseType(process.env.DATABASE_URL);
|
||||
|
||||
if (db === POSTGRESQL) {
|
||||
@ -207,7 +172,7 @@ function parseFilters(
|
||||
};
|
||||
}
|
||||
|
||||
async function rawQuery(query, params = []): Promise<any> {
|
||||
async function rawQuery(query: string, params: never[] = []): Promise<any> {
|
||||
const db = getDatabaseType(process.env.DATABASE_URL);
|
||||
|
||||
if (db !== POSTGRESQL && db !== MYSQL) {
|
||||
@ -216,20 +181,11 @@ async function rawQuery(query, params = []): Promise<any> {
|
||||
|
||||
const sql = db === MYSQL ? query.replace(/\$[0-9]+/g, '?') : query;
|
||||
|
||||
return prisma.$queryRawUnsafe.apply(prisma, [sql, ...params]);
|
||||
return prisma.rawQuery(sql, params);
|
||||
}
|
||||
|
||||
async function transaction(queries): Promise<any> {
|
||||
return prisma.$transaction(queries);
|
||||
}
|
||||
|
||||
// Initialization
|
||||
const prisma: PrismaClient<PrismaClientOptions, 'query' | 'error' | 'info' | 'warn'> =
|
||||
global[PRISMA] || getClient(PRISMA_OPTIONS);
|
||||
|
||||
export default {
|
||||
client: prisma,
|
||||
log,
|
||||
...prisma,
|
||||
getDateQuery,
|
||||
getTimestampInterval,
|
||||
getFilterQuery,
|
||||
@ -237,5 +193,4 @@ export default {
|
||||
getEventDataFilterQuery,
|
||||
parseFilters,
|
||||
rawQuery,
|
||||
transaction,
|
||||
};
|
||||
|
62
lib/redis.js
62
lib/redis.js
@ -1,62 +0,0 @@
|
||||
import { createClient } from 'redis';
|
||||
import debug from 'debug';
|
||||
|
||||
const log = debug('umami:redis');
|
||||
const REDIS = Symbol();
|
||||
const DELETED = 'DELETED';
|
||||
|
||||
let redis;
|
||||
const url = process.env.REDIS_URL;
|
||||
const enabled = Boolean(url);
|
||||
|
||||
async function getClient() {
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const client = createClient({ url });
|
||||
client.on('error', err => log(err));
|
||||
await client.connect();
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
global[REDIS] = client;
|
||||
}
|
||||
|
||||
log('Redis initialized');
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
async function get(key) {
|
||||
await connect();
|
||||
|
||||
const data = await redis.get(key);
|
||||
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function set(key, value) {
|
||||
await connect();
|
||||
|
||||
return redis.set(key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
async function del(key) {
|
||||
await connect();
|
||||
|
||||
return redis.del(key);
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
if (!redis && enabled) {
|
||||
redis = global[REDIS] || (await getClient());
|
||||
}
|
||||
|
||||
return redis;
|
||||
}
|
||||
|
||||
export default { enabled, client: redis, log, connect, get, set, del, DELETED };
|
@ -61,6 +61,8 @@
|
||||
"@fontsource/inter": "4.5.7",
|
||||
"@prisma/client": "4.8.0",
|
||||
"@tanstack/react-query": "^4.16.1",
|
||||
"@umami/prisma-client": "^0.1.0",
|
||||
"@umami/redis-client": "^0.1.0",
|
||||
"chalk": "^4.1.1",
|
||||
"chart.js": "^2.9.4",
|
||||
"classnames": "^2.3.1",
|
||||
|
@ -7,9 +7,9 @@ import {
|
||||
methodNotAllowed,
|
||||
getRandomChars,
|
||||
} from 'next-basics';
|
||||
import redis from '@umami/redis-client';
|
||||
import { getUser, User } from 'queries';
|
||||
import { secret } from 'lib/crypto';
|
||||
import redis from 'lib/redis';
|
||||
import { NextApiRequestQueryBody } from 'lib/types';
|
||||
import { NextApiResponse } from 'next';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { methodNotAllowed, ok } from 'next-basics';
|
||||
import redis from '@umami/redis-client';
|
||||
import { useAuth } from 'lib/middleware';
|
||||
import redis from 'lib/redis';
|
||||
import { getAuthToken } from 'lib/auth';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
|
17
yarn.lock
17
yarn.lock
@ -2290,6 +2290,21 @@
|
||||
"@typescript-eslint/types" "5.45.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@umami/prisma-client@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@umami/prisma-client/-/prisma-client-0.1.0.tgz#4ecc17b1998cb738b8f2027b80b003864beef6a4"
|
||||
integrity sha512-2qTXN0dtMUT+HVhz37eVC02lDSwz9TGUGHRRO0LPRHdfJPfSkUF0D8pgksX7ETy3IZoIQP1h45tiXsM0pKBMZA==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
|
||||
"@umami/redis-client@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@umami/redis-client/-/redis-client-0.1.0.tgz#69599b1243406a3aef83927bb8655a3ef4c0c031"
|
||||
integrity sha512-XCqCdc3xA5KDOorIUvOVlz+/F/SEyL9cKWfCCGYYZix1b9yFo+5BzM0C0q7Yu/qV+1jYd+viNsBQQSM6a8sfjg==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
redis "^4.5.1"
|
||||
|
||||
"@vercel/node-bridge@^2.1.0":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/node-bridge/-/node-bridge-2.2.2.tgz#f63466ab6a2588afdc6262c2d060289bfe8baa6b"
|
||||
@ -6632,7 +6647,7 @@ redis-parser@^3.0.0:
|
||||
dependencies:
|
||||
redis-errors "^1.0.0"
|
||||
|
||||
redis@^4.5.0:
|
||||
redis@^4.5.0, redis@^4.5.1:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/redis/-/redis-4.5.1.tgz#f5a818970bb2dc5d60540bab41308640604c7d33"
|
||||
integrity sha512-oxXSoIqMJCQVBTfxP6BNTCtDMyh9G6Vi5wjdPdV/sRKkufyZslDqCScSGcOr6XGR/reAWZefz7E4leM31RgdBA==
|
||||
|
Loading…
Reference in New Issue
Block a user