{data && !error && limit && (
-
+
{formatMessage(labels.more)}
diff --git a/src/components/metrics/PagesTable.tsx b/src/components/metrics/PagesTable.tsx
index 9b3df418..4bc5c461 100644
--- a/src/components/metrics/PagesTable.tsx
+++ b/src/components/metrics/PagesTable.tsx
@@ -12,13 +12,13 @@ export interface PagesTableProps extends MetricsTableProps {
export function PagesTable({ allowFilter, domainName, ...props }: PagesTableProps) {
const {
router,
- makeUrl,
+ renderUrl,
query: { view = 'url' },
} = useNavigation();
const { formatMessage, labels } = useMessages();
const handleSelect = (key: any) => {
- router.push(makeUrl({ view: key }), { scroll: true });
+ router.push(renderUrl({ view: key }), { scroll: true });
};
const buttons = [
diff --git a/src/lib/cache.ts b/src/lib/cache.ts
index 69d749d0..97482499 100644
--- a/src/lib/cache.ts
+++ b/src/lib/cache.ts
@@ -1,12 +1,12 @@
import { User, Website } from '@prisma/client';
import redis from '@umami/redis-client';
-import { getSession, getUserById, getWebsiteById } from '../queries';
+import { getSession, getUser, getWebsite } from '../queries';
-async function fetchWebsite(id): Promise {
- return redis.client.getCache(`website:${id}`, () => getWebsiteById(id), 86400);
+async function fetchWebsite(websiteId: string): Promise {
+ return redis.client.getCache(`website:${websiteId}`, () => getWebsite(websiteId), 86400);
}
-async function storeWebsite(data) {
+async function storeWebsite(data: { id: any }) {
const { id } = data;
const key = `website:${id}`;
@@ -21,11 +21,7 @@ async function deleteWebsite(id) {
}
async function fetchUser(id): Promise {
- return redis.client.getCache(
- `user:${id}`,
- () => getUserById(id, { includePassword: true }),
- 86400,
- );
+ return redis.client.getCache(`user:${id}`, () => getUser(id, { includePassword: true }), 86400);
}
async function storeUser(data) {
diff --git a/src/lib/load.ts b/src/lib/load.ts
index d980f8e9..78c0ac9c 100644
--- a/src/lib/load.ts
+++ b/src/lib/load.ts
@@ -1,5 +1,5 @@
import cache from 'lib/cache';
-import { getSession, getUserById, getWebsiteById } from 'queries';
+import { getSession, getUser, getWebsite } from 'queries';
import { User, Website, Session } from '@prisma/client';
export async function loadWebsite(websiteId: string): Promise {
@@ -8,7 +8,7 @@ export async function loadWebsite(websiteId: string): Promise {
if (cache.enabled) {
website = await cache.fetchWebsite(websiteId);
} else {
- website = await getWebsiteById(websiteId);
+ website = await getWebsite(websiteId);
}
if (!website || website.deletedAt) {
@@ -40,7 +40,7 @@ export async function loadUser(userId: string): Promise {
if (cache.enabled) {
user = await cache.fetchUser(userId);
} else {
- user = await getUserById(userId);
+ user = await getUser(userId);
}
if (!user || user.deletedAt) {
diff --git a/src/lib/middleware.ts b/src/lib/middleware.ts
index 91fb6c7c..6885de90 100644
--- a/src/lib/middleware.ts
+++ b/src/lib/middleware.ts
@@ -14,7 +14,7 @@ import {
unauthorized,
} from 'next-basics';
import { NextApiRequestCollect } from 'pages/api/send';
-import { getUserById } from '../queries';
+import { getUser } from '../queries';
const log = debug('umami:middleware');
@@ -57,12 +57,12 @@ export const useAuth = createMiddleware(async (req, res, next) => {
const { userId, authKey, grant } = payload || {};
if (userId) {
- user = await getUserById(userId);
+ user = await getUser(userId);
} else if (redis.enabled && authKey) {
const key = await redis.client.get(authKey);
if (key?.userId) {
- user = await getUserById(key.userId);
+ user = await getUser(key.userId);
}
}
diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts
index 1a8e0ba5..ea2d849e 100644
--- a/src/lib/prisma.ts
+++ b/src/lib/prisma.ts
@@ -175,24 +175,12 @@ async function rawQuery(sql: string, data: object): Promise {
return prisma.rawQuery(query, params);
}
-function getPageFilters(filters: SearchFilter): [
- {
- orderBy: {
- [x: string]: string;
- }[];
- take: number;
- skip: number;
- },
- {
- pageSize: number;
- page: number;
- orderBy: string;
- },
-] {
+async function pagedQuery(model: string, criteria: T, filters: SearchFilter) {
const { page = 1, pageSize = DEFAULT_PAGE_SIZE, orderBy, sortDescending = false } = filters || {};
- return [
- {
+ const data = await prisma.client[model].findMany({
+ ...criteria,
+ ...{
...(pageSize > 0 && { take: +pageSize, skip: +pageSize * (page - 1) }),
...(orderBy && {
orderBy: [
@@ -202,8 +190,11 @@ function getPageFilters(filters: SearchFilter): [
],
}),
},
- { page: +page, pageSize, orderBy },
- ];
+ });
+
+ const count = await prisma.client[model].count({ where: (criteria as any).where });
+
+ return { data, count, page: +page, pageSize, orderBy };
}
function getQueryMode(): Prisma.QueryMode {
@@ -225,7 +216,7 @@ export default {
getTimestampDiffQuery,
getFilterQuery,
parseFilters,
- getPageFilters,
getQueryMode,
rawQuery,
+ pagedQuery,
};
diff --git a/src/lib/types.ts b/src/lib/types.ts
index e08ba2d0..b034e18a 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -38,6 +38,10 @@ export interface TeamSearchFilter extends SearchFilter {
userId?: string;
}
+export interface TeamUserSearchFilter extends SearchFilter {
+ teamId?: string;
+}
+
export interface ReportSearchFilter extends SearchFilter {
userId?: string;
websiteId?: string;
diff --git a/src/pages/api/admin/users.ts b/src/pages/api/admin/users.ts
index 3ded1167..63f27727 100644
--- a/src/pages/api/admin/users.ts
+++ b/src/pages/api/admin/users.ts
@@ -42,10 +42,7 @@ export default async (
return unauthorized(res);
}
- const { page, query, pageSize } = req.query;
-
const users = await getUsers(
- { page, query, pageSize: +pageSize || undefined },
{
include: {
_count: {
@@ -57,6 +54,7 @@ export default async (
},
},
},
+ req.query,
);
return ok(res, users);
diff --git a/src/pages/api/admin/websites.ts b/src/pages/api/admin/websites.ts
index 13c19072..4fbcd5cc 100644
--- a/src/pages/api/admin/websites.ts
+++ b/src/pages/api/admin/websites.ts
@@ -39,25 +39,19 @@ export default async (
return unauthorized(res);
}
- const websites = await getWebsites(req.query, {
- include: {
- teamWebsite: {
- include: {
- team: {
- select: {
- name: true,
- },
+ const websites = await getWebsites(
+ {
+ include: {
+ user: {
+ select: {
+ username: true,
+ id: true,
},
},
},
- user: {
- select: {
- username: true,
- id: true,
- },
- },
},
- });
+ req.query,
+ );
return ok(res, websites);
}
diff --git a/src/pages/api/auth/verify.ts b/src/pages/api/auth/verify.ts
index a302c69b..ddd4a1a8 100644
--- a/src/pages/api/auth/verify.ts
+++ b/src/pages/api/auth/verify.ts
@@ -2,9 +2,16 @@ import { NextApiRequestAuth } from 'lib/types';
import { useAuth } from 'lib/middleware';
import { NextApiResponse } from 'next';
import { ok } from 'next-basics';
+import { getUserTeams } from 'queries/admin/team';
export default async (req: NextApiRequestAuth, res: NextApiResponse) => {
await useAuth(req, res);
- return ok(res, req.auth.user);
+ const { user } = req.auth;
+
+ const teams = await getUserTeams(user.id);
+
+ user['teams'] = teams.data.map(n => n);
+
+ return ok(res, user);
};
diff --git a/src/pages/api/me/password.ts b/src/pages/api/me/password.ts
index 5b7a8e05..24cd2517 100644
--- a/src/pages/api/me/password.ts
+++ b/src/pages/api/me/password.ts
@@ -9,7 +9,7 @@ import {
methodNotAllowed,
ok,
} from 'next-basics';
-import { getUserById, updateUser } from 'queries';
+import { getUser, updateUser } from 'queries';
import * as yup from 'yup';
export interface UserPasswordRequestQuery {
@@ -43,7 +43,7 @@ export default async (
const { id } = req.auth.user;
if (req.method === 'POST') {
- const user = await getUserById(id, { includePassword: true });
+ const user = await getUser(id, { includePassword: true });
if (!checkPassword(currentPassword, user.password)) {
return badRequest(res, 'Current password is incorrect');
diff --git a/src/pages/api/reports/[id].ts b/src/pages/api/reports/[id].ts
index 02eb7363..db86631f 100644
--- a/src/pages/api/reports/[id].ts
+++ b/src/pages/api/reports/[id].ts
@@ -3,7 +3,7 @@ import { useAuth, useCors, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody, ReportType, YupRequest } from 'lib/types';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { deleteReport, getReportById, updateReport } from 'queries';
+import { deleteReport, getReport, updateReport } from 'queries';
import * as yup from 'yup';
export interface ReportRequestQuery {
@@ -54,7 +54,7 @@ export default async (
} = req.auth;
if (req.method === 'GET') {
- const report = await getReportById(reportId);
+ const report = await getReport(reportId);
if (!(await canViewReport(req.auth, report))) {
return unauthorized(res);
@@ -68,7 +68,7 @@ export default async (
if (req.method === 'POST') {
const { websiteId, type, name, description, parameters } = req.body;
- const report = await getReportById(reportId);
+ const report = await getReport(reportId);
if (!(await canUpdateReport(req.auth, report))) {
return unauthorized(res);
@@ -87,7 +87,7 @@ export default async (
}
if (req.method === 'DELETE') {
- const report = await getReportById(reportId);
+ const report = await getReport(reportId);
if (!(await canDeleteReport(req.auth, report))) {
return unauthorized(res);
diff --git a/src/pages/api/reports/index.ts b/src/pages/api/reports/index.ts
index 82902aef..29456a41 100644
--- a/src/pages/api/reports/index.ts
+++ b/src/pages/api/reports/index.ts
@@ -4,7 +4,7 @@ import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { pageInfo } from 'lib/schema';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok } from 'next-basics';
-import { createReport, getReportsByUserId } from 'queries';
+import { createReport, getUserReports } from 'queries';
import * as yup from 'yup';
export interface ReportsRequestQuery extends SearchFilter {}
@@ -52,11 +52,10 @@ export default async (
if (req.method === 'GET') {
const { page, query, pageSize } = req.query;
- const data = await getReportsByUserId(userId, {
+ const data = await getUserReports(userId, {
page,
pageSize: +pageSize || undefined,
query,
- includeTeams: true,
});
return ok(res, data);
diff --git a/src/pages/api/share/[id].ts b/src/pages/api/share/[id].ts
index 876fbef5..27688e23 100644
--- a/src/pages/api/share/[id].ts
+++ b/src/pages/api/share/[id].ts
@@ -3,7 +3,7 @@ import { useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody } from 'lib/types';
import { NextApiResponse } from 'next';
import { createToken, methodNotAllowed, notFound, ok } from 'next-basics';
-import { getWebsiteByShareId } from 'queries';
+import { getSharedWebsite } from 'queries';
import * as yup from 'yup';
export interface ShareRequestQuery {
@@ -30,7 +30,7 @@ export default async (
const { id: shareId } = req.query;
if (req.method === 'GET') {
- const website = await getWebsiteByShareId(shareId);
+ const website = await getSharedWebsite(shareId);
if (website) {
const data = { websiteId: website.id };
diff --git a/src/pages/api/teams/[id]/index.ts b/src/pages/api/teams/[id]/index.ts
index 8d2c2f6c..17ca675a 100644
--- a/src/pages/api/teams/[id]/index.ts
+++ b/src/pages/api/teams/[id]/index.ts
@@ -4,7 +4,7 @@ import { useAuth, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody } from 'lib/types';
import { NextApiResponse } from 'next';
import { methodNotAllowed, notFound, ok, unauthorized } from 'next-basics';
-import { deleteTeam, getTeamById, updateTeam } from 'queries';
+import { deleteTeam, getTeam, updateTeam } from 'queries';
import * as yup from 'yup';
export interface TeamRequestQuery {
@@ -44,7 +44,7 @@ export default async (
return unauthorized(res);
}
- const team = await getTeamById(teamId, { includeTeamUser: true });
+ const team = await getTeam(teamId, { includeMembers: true });
if (!team) {
return notFound(res);
diff --git a/src/pages/api/teams/[id]/users/index.ts b/src/pages/api/teams/[id]/users/index.ts
index 0440cd74..f4eab36a 100644
--- a/src/pages/api/teams/[id]/users/index.ts
+++ b/src/pages/api/teams/[id]/users/index.ts
@@ -4,7 +4,7 @@ import { pageInfo } from 'lib/schema';
import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { NextApiResponse } from 'next';
import { badRequest, methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { createTeamUser, getTeamUser, getUsersByTeamId } from 'queries';
+import { createTeamUser, getTeamUser, getTeamUsers } from 'queries';
import * as yup from 'yup';
export interface TeamUserRequestQuery extends SearchFilter {
@@ -46,7 +46,7 @@ export default async (
const { query, page, pageSize } = req.query;
- const users = await getUsersByTeamId(teamId, {
+ const users = await getTeamUsers(teamId, {
query,
page,
pageSize: +pageSize || undefined,
diff --git a/src/pages/api/teams/[id]/websites/index.ts b/src/pages/api/teams/[id]/websites/index.ts
index 33bb4207..b5e15210 100644
--- a/src/pages/api/teams/[id]/websites/index.ts
+++ b/src/pages/api/teams/[id]/websites/index.ts
@@ -5,7 +5,7 @@ import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { pageInfo } from 'lib/schema';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { createWebsite, getWebsitesByTeamId } from 'queries';
+import { createWebsite, getTeamWebsites } from 'queries';
import { uuid } from 'lib/crypto';
export interface TeamWebsiteRequestQuery extends SearchFilter {
@@ -46,7 +46,7 @@ export default async (
const { page, query, pageSize } = req.query;
- const websites = await getWebsitesByTeamId(teamId, {
+ const websites = await getTeamWebsites(teamId, {
page,
query,
pageSize: +pageSize || undefined,
diff --git a/src/pages/api/teams/index.ts b/src/pages/api/teams/index.ts
index e89b4ee8..7684f306 100644
--- a/src/pages/api/teams/index.ts
+++ b/src/pages/api/teams/index.ts
@@ -6,7 +6,7 @@ import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { pageInfo } from 'lib/schema';
import { NextApiResponse } from 'next';
import { getRandomChars, methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { createTeam, getTeamsByUserId } from 'queries';
+import { createTeam, getUserTeams } from 'queries';
import * as yup from 'yup';
export interface TeamsRequestQuery extends SearchFilter {}
@@ -37,7 +37,7 @@ export default async (
if (req.method === 'GET') {
const { page, query, pageSize } = req.query;
- const results = await getTeamsByUserId(userId, {
+ const results = await getUserTeams(userId, {
page,
query,
pageSize: +pageSize || undefined,
diff --git a/src/pages/api/teams/join.ts b/src/pages/api/teams/join.ts
index 0f9d01fa..ff4768d8 100644
--- a/src/pages/api/teams/join.ts
+++ b/src/pages/api/teams/join.ts
@@ -4,7 +4,7 @@ import { useAuth, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody } from 'lib/types';
import { NextApiResponse } from 'next';
import { methodNotAllowed, notFound, ok } from 'next-basics';
-import { createTeamUser, getTeamByAccessCode, getTeamUser } from 'queries';
+import { createTeamUser, findTeam, getTeamUser } from 'queries';
import * as yup from 'yup';
export interface TeamsJoinRequestBody {
accessCode: string;
@@ -26,7 +26,11 @@ export default async (
if (req.method === 'POST') {
const { accessCode } = req.body;
- const team = await getTeamByAccessCode(accessCode);
+ const team = await findTeam({
+ where: {
+ accessCode,
+ },
+ });
if (!team) {
return notFound(res, 'message.team-not-found');
diff --git a/src/pages/api/users/[id]/index.ts b/src/pages/api/users/[id]/index.ts
index 7926d34a..495d41cc 100644
--- a/src/pages/api/users/[id]/index.ts
+++ b/src/pages/api/users/[id]/index.ts
@@ -3,7 +3,7 @@ import { useAuth, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody, Role, User } from 'lib/types';
import { NextApiResponse } from 'next';
import { badRequest, hashPassword, methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { deleteUser, getUserById, getUserByUsername, updateUser } from 'queries';
+import { deleteUser, getUser, getUserByUsername, updateUser } from 'queries';
import * as yup from 'yup';
export interface UserRequestQuery {
@@ -45,7 +45,7 @@ export default async (
return unauthorized(res);
}
- const user = await getUserById(id);
+ const user = await getUser(id);
return ok(res, user);
}
@@ -57,7 +57,7 @@ export default async (
const { username, password, role } = req.body;
- const user = await getUserById(id);
+ const user = await getUser(id);
const data: any = {};
diff --git a/src/pages/api/users/[id]/teams.ts b/src/pages/api/users/[id]/teams.ts
index cb5d4448..632a26a0 100644
--- a/src/pages/api/users/[id]/teams.ts
+++ b/src/pages/api/users/[id]/teams.ts
@@ -4,7 +4,7 @@ import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { pageInfo } from 'lib/schema';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { getTeamsByUserId } from 'queries';
+import { getUserTeams } from 'queries';
export interface UserTeamsRequestQuery extends SearchFilter {
id: string;
@@ -41,7 +41,7 @@ export default async (
const { page, query, pageSize } = req.query;
- const teams = await getTeamsByUserId(userId, {
+ const teams = await getUserTeams(userId, {
query,
page,
pageSize: +pageSize || undefined,
diff --git a/src/pages/api/users/[id]/usage.ts b/src/pages/api/users/[id]/usage.ts
index 7cb40d61..72b33e3e 100644
--- a/src/pages/api/users/[id]/usage.ts
+++ b/src/pages/api/users/[id]/usage.ts
@@ -2,7 +2,7 @@ import { useAuth, useCors, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody } from 'lib/types';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { getEventDataUsage, getEventUsage, getUserWebsites } from 'queries';
+import { getAllWebsites, getEventDataUsage, getEventUsage } from 'queries';
import * as yup from 'yup';
export interface UserUsageRequestQuery {
@@ -26,7 +26,7 @@ const schema = {
GET: yup.object().shape({
id: yup.string().uuid().required(),
startAt: yup.number().integer().required(),
- endAt: yup.number().integer().moreThan(yup.ref('startAt')).required(),
+ endAt: yup.number().integer().moreThan(yup.ref('startAt')).required(),
}),
};
@@ -50,7 +50,7 @@ export default async (
const startDate = new Date(+startAt);
const endDate = new Date(+endAt);
- const websites = await getUserWebsites(userId);
+ const websites = await getAllWebsites(userId);
const websiteIds = websites.map(a => a.id);
diff --git a/src/pages/api/users/[id]/websites.ts b/src/pages/api/users/[id]/websites.ts
index b5ca5cdb..afd93fe1 100644
--- a/src/pages/api/users/[id]/websites.ts
+++ b/src/pages/api/users/[id]/websites.ts
@@ -3,7 +3,7 @@ import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { pageInfo } from 'lib/schema';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { getWebsitesByUserId } from 'queries';
+import { getUserWebsites } from 'queries';
import * as yup from 'yup';
export interface UserWebsitesRequestQuery extends SearchFilter {
@@ -37,7 +37,7 @@ export default async (
return unauthorized(res);
}
- const websites = await getWebsitesByUserId(userId, {
+ const websites = await getUserWebsites(userId, {
page,
pageSize: +pageSize || undefined,
query,
diff --git a/src/pages/api/websites/[id]/index.ts b/src/pages/api/websites/[id]/index.ts
index 02e31786..79544919 100644
--- a/src/pages/api/websites/[id]/index.ts
+++ b/src/pages/api/websites/[id]/index.ts
@@ -3,7 +3,7 @@ import { methodNotAllowed, ok, serverError, unauthorized } from 'next-basics';
import { Website, NextApiRequestQueryBody } from 'lib/types';
import { canViewWebsite, canUpdateWebsite, canDeleteWebsite } from 'lib/auth';
import { useAuth, useCors, useValidate } from 'lib/middleware';
-import { deleteWebsite, getWebsiteById, updateWebsite } from 'queries';
+import { deleteWebsite, getWebsite, updateWebsite } from 'queries';
import { SHARE_ID_REGEX } from 'lib/constants';
export interface WebsiteRequestQuery {
@@ -45,7 +45,7 @@ export default async (
return unauthorized(res);
}
- const website = await getWebsiteById(websiteId);
+ const website = await getWebsite(websiteId);
return ok(res, website);
}
diff --git a/src/pages/api/websites/[id]/reports.ts b/src/pages/api/websites/[id]/reports.ts
index 18e944fe..f5a47eb9 100644
--- a/src/pages/api/websites/[id]/reports.ts
+++ b/src/pages/api/websites/[id]/reports.ts
@@ -4,7 +4,7 @@ import { useAuth, useCors, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody, SearchFilter } from 'lib/types';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { getReportsByWebsiteId } from 'queries';
+import { getWebsiteReports } from 'queries';
import { pageInfo } from 'lib/schema';
export interface ReportsRequestQuery extends SearchFilter {
@@ -35,7 +35,7 @@ export default async (
const { page, query, pageSize } = req.query;
- const data = await getReportsByWebsiteId(websiteId, {
+ const data = await getWebsiteReports(websiteId, {
page,
pageSize: +pageSize || undefined,
query,
diff --git a/src/queries/admin/report.ts b/src/queries/admin/report.ts
index 9077431f..76f1161b 100644
--- a/src/queries/admin/report.ts
+++ b/src/queries/admin/report.ts
@@ -1,39 +1,30 @@
import { Prisma, Report } from '@prisma/client';
import prisma from 'lib/prisma';
import { FilterResult, ReportSearchFilter } from 'lib/types';
+import ReportFindUniqueArgs = Prisma.ReportFindUniqueArgs;
+import ReportFindManyArgs = Prisma.ReportFindManyArgs;
-export async function createReport(data: Prisma.ReportUncheckedCreateInput): Promise {
- return prisma.client.report.create({ data });
+async function findReport(criteria: ReportFindUniqueArgs) {
+ return prisma.client.report.findUnique(criteria);
}
-export async function getReportById(reportId: string): Promise {
- return prisma.client.report.findUnique({
+export async function getReport(reportId: string): Promise {
+ return findReport({
where: {
id: reportId,
},
});
}
-export async function updateReport(
- reportId: string,
- data: Prisma.ReportUpdateInput,
-): Promise {
- return prisma.client.report.update({ where: { id: reportId }, data });
-}
-
-export async function deleteReport(reportId: string): Promise {
- return prisma.client.report.delete({ where: { id: reportId } });
-}
-
export async function getReports(
- params: ReportSearchFilter,
- options?: { include?: Prisma.ReportInclude },
+ criteria: ReportFindManyArgs,
+ filters: ReportSearchFilter = {},
): Promise> {
- const { query, userId, websiteId } = params;
-
const mode = prisma.getQueryMode();
+ const { query, userId, websiteId } = filters;
const where: Prisma.ReportWhereInput = {
+ ...criteria.where,
userId,
websiteId,
AND: [
@@ -93,32 +84,18 @@ export async function getReports(
],
};
- const [pageFilters, pageInfo] = prisma.getPageFilters(params);
-
- const reports = await prisma.client.report.findMany({
- where,
- ...pageFilters,
- ...(options?.include && { include: options.include }),
- });
-
- const count = await prisma.client.report.count({
- where,
- });
-
- return {
- data: reports,
- count,
- ...pageInfo,
- };
+ return prisma.pagedQuery('report', { where }, filters);
}
-export async function getReportsByUserId(
+export async function getUserReports(
userId: string,
- filter?: ReportSearchFilter,
+ filters?: ReportSearchFilter,
): Promise> {
return getReports(
- { userId, ...filter },
{
+ where: {
+ userId,
+ },
include: {
website: {
select: {
@@ -128,12 +105,35 @@ export async function getReportsByUserId(
},
},
},
+ filters,
);
}
-export async function getReportsByWebsiteId(
+export async function getWebsiteReports(
websiteId: string,
- filter: ReportSearchFilter,
+ filters: ReportSearchFilter = {},
): Promise> {
- return getReports({ websiteId, ...filter });
+ return getReports(
+ {
+ where: {
+ websiteId,
+ },
+ },
+ filters,
+ );
+}
+
+export async function createReport(data: Prisma.ReportUncheckedCreateInput): Promise {
+ return prisma.client.report.create({ data });
+}
+
+export async function updateReport(
+ reportId: string,
+ data: Prisma.ReportUpdateInput,
+): Promise {
+ return prisma.client.report.update({ where: { id: reportId }, data });
+}
+
+export async function deleteReport(reportId: string): Promise {
+ return prisma.client.report.delete({ where: { id: reportId } });
}
diff --git a/src/queries/admin/team.ts b/src/queries/admin/team.ts
index 08d16909..0686fc26 100644
--- a/src/queries/admin/team.ts
+++ b/src/queries/admin/team.ts
@@ -3,29 +3,109 @@ import { ROLES } from 'lib/constants';
import { uuid } from 'lib/crypto';
import prisma from 'lib/prisma';
import { FilterResult, TeamSearchFilter } from 'lib/types';
+import TeamFindManyArgs = Prisma.TeamFindManyArgs;
-export interface GetTeamOptions {
- includeTeamUser?: boolean;
+export async function findTeam(criteria: Prisma.TeamFindFirstArgs): Promise {
+ return prisma.client.team.findFirst(criteria);
}
-async function getTeam(where: Prisma.TeamWhereInput, options: GetTeamOptions = {}): Promise {
- const { includeTeamUser = false } = options;
- const { client } = prisma;
+export async function getTeam(teamId: string, options: { includeMembers?: boolean } = {}) {
+ const { includeMembers } = options;
- return client.team.findFirst({
- where,
- include: {
- teamUser: includeTeamUser,
+ return findTeam({
+ where: {
+ id: teamId,
},
+ ...(includeMembers && { include: { teamUser: true } }),
});
}
-export function getTeamById(teamId: string, options: GetTeamOptions = {}) {
- return getTeam({ id: teamId }, options);
+export async function getTeams(
+ criteria: TeamFindManyArgs,
+ filters: TeamSearchFilter = {},
+): Promise> {
+ const mode = prisma.getQueryMode();
+ const { userId, query } = filters;
+
+ const where: Prisma.TeamWhereInput = {
+ ...criteria.where,
+ ...(userId && {
+ teamUser: {
+ some: { userId },
+ },
+ }),
+ ...(query && {
+ AND: {
+ OR: [
+ {
+ name: {
+ startsWith: query,
+ mode,
+ },
+ },
+ {
+ teamUser: {
+ some: {
+ role: ROLES.teamOwner,
+ user: {
+ username: {
+ startsWith: query,
+ mode,
+ },
+ },
+ },
+ },
+ },
+ ],
+ },
+ }),
+ };
+
+ return prisma.pagedQuery(
+ 'team',
+ {
+ ...criteria,
+ where,
+ },
+ filters,
+ );
}
-export function getTeamByAccessCode(accessCode: string, options: GetTeamOptions = {}) {
- return getTeam({ accessCode }, options);
+export async function getUserTeams(userId: string, filters: TeamSearchFilter = {}) {
+ return getTeams(
+ {
+ where: {
+ teamUser: {
+ some: { userId },
+ },
+ },
+ include: {
+ teamUser: {
+ include: {
+ user: {
+ select: {
+ id: true,
+ username: true,
+ },
+ },
+ },
+ },
+ _count: {
+ select: {
+ website: {
+ where: { deletedAt: null },
+ },
+ teamUser: {
+ where: {
+ user: { deletedAt: null },
+ },
+ },
+ },
+ },
+ },
+ },
+ filters,
+ );
}
export async function createTeam(data: Prisma.TeamCreateInput, userId: string): Promise {
@@ -93,94 +173,3 @@ export async function deleteTeam(
}),
]);
}
-
-export async function getTeams(
- filters: TeamSearchFilter,
- options?: { include?: Prisma.TeamInclude },
-): Promise> {
- const { userId, query } = filters;
- const mode = prisma.getQueryMode();
- const { client } = prisma;
-
- const where: Prisma.TeamWhereInput = {
- ...(userId && {
- teamUser: {
- some: { userId },
- },
- }),
- ...(query && {
- AND: {
- OR: [
- {
- name: { startsWith: query, mode },
- },
- {
- teamUser: {
- some: {
- role: ROLES.teamOwner,
- user: {
- username: {
- startsWith: query,
- mode,
- },
- },
- },
- },
- },
- ],
- },
- }),
- };
-
- const [pageFilters, getParameters] = prisma.getPageFilters({
- orderBy: 'name',
- ...filters,
- });
-
- const teams = await client.team.findMany({
- where: {
- ...where,
- },
- ...pageFilters,
- ...(options?.include && { include: options?.include }),
- });
-
- const count = await client.team.count({ where });
-
- return { data: teams, count, ...getParameters };
-}
-
-export async function getTeamsByUserId(
- userId: string,
- filter?: TeamSearchFilter,
-): Promise> {
- return getTeams(
- { userId, ...filter },
- {
- include: {
- teamUser: {
- include: {
- user: {
- select: {
- id: true,
- username: true,
- },
- },
- },
- },
- _count: {
- select: {
- website: {
- where: { deletedAt: null },
- },
- teamUser: {
- where: {
- user: { deletedAt: null },
- },
- },
- },
- },
- },
- },
- );
-}
diff --git a/src/queries/admin/teamUser.ts b/src/queries/admin/teamUser.ts
index 7da5d292..4153449a 100644
--- a/src/queries/admin/teamUser.ts
+++ b/src/queries/admin/teamUser.ts
@@ -1,14 +1,7 @@
-import { Prisma, TeamUser } from '@prisma/client';
+import { TeamUser } from '@prisma/client';
import { uuid } from 'lib/crypto';
import prisma from 'lib/prisma';
-
-export async function getTeamUserById(teamUserId: string): Promise {
- return prisma.client.teamUser.findUnique({
- where: {
- id: teamUserId,
- },
- });
-}
+import { FilterResult, TeamUserSearchFilter } from 'lib/types';
export async function getTeamUser(teamId: string, userId: string): Promise {
return prisma.client.teamUser.findFirst({
@@ -21,20 +14,25 @@ export async function getTeamUser(teamId: string, userId: string): Promise {
- return prisma.client.teamUser.findMany({
- where: {
- teamId,
- },
- include: {
- user: {
- select: {
- id: true,
- username: true,
+ filters?: TeamUserSearchFilter,
+): Promise> {
+ return prisma.pagedQuery(
+ 'teamUser',
+ {
+ where: {
+ teamId,
+ },
+ include: {
+ user: {
+ select: {
+ id: true,
+ username: true,
+ },
},
},
},
- });
+ filters,
+ );
}
export async function createTeamUser(
@@ -52,18 +50,6 @@ export async function createTeamUser(
});
}
-export async function updateTeamUser(
- teamUserId: string,
- data: Prisma.TeamUserUpdateInput,
-): Promise {
- return prisma.client.teamUser.update({
- where: {
- id: teamUserId,
- },
- data,
- });
-}
-
export async function deleteTeamUser(teamId: string, userId: string): Promise {
const { client } = prisma;
@@ -74,15 +60,3 @@ export async function deleteTeamUser(teamId: string, userId: string): Promise {
- return prisma.client.teamUser.deleteMany({
- where: {
- userId,
- teamId,
- },
- });
-}
diff --git a/src/queries/admin/user.ts b/src/queries/admin/user.ts
index 51dda2d4..da8de255 100644
--- a/src/queries/admin/user.ts
+++ b/src/queries/admin/user.ts
@@ -4,24 +4,25 @@ import { ROLES } from 'lib/constants';
import prisma from 'lib/prisma';
import { FilterResult, Role, User, UserSearchFilter } from 'lib/types';
import { getRandomChars } from 'next-basics';
+import UserFindManyArgs = Prisma.UserFindManyArgs;
export interface GetUserOptions {
includePassword?: boolean;
showDeleted?: boolean;
}
-async function getUser(
- where: Prisma.UserWhereUniqueInput,
+async function findUser(
+ criteria: Prisma.UserFindUniqueArgs,
options: GetUserOptions = {},
): Promise {
const { includePassword = false, showDeleted = false } = options;
- if (showDeleted) {
- where.deletedAt = null;
- }
-
return prisma.client.user.findUnique({
- where,
+ ...criteria,
+ where: {
+ ...criteria.where,
+ ...(showDeleted && { delatedAt: null }),
+ },
select: {
id: true,
username: true,
@@ -32,19 +33,26 @@ async function getUser(
});
}
-export async function getUserById(id: string, options: GetUserOptions = {}) {
- return getUser({ id }, options);
+export async function getUser(userId: string, options: GetUserOptions = {}) {
+ return findUser(
+ {
+ where: {
+ id: userId,
+ },
+ },
+ options,
+ );
}
export async function getUserByUsername(username: string, options: GetUserOptions = {}) {
- return getUser({ username }, options);
+ return findUser({ where: { username } }, options);
}
export async function getUsers(
- params: UserSearchFilter,
- options?: { include?: Prisma.UserInclude },
+ criteria: UserFindManyArgs,
+ filters?: UserSearchFilter,
): Promise> {
- const { teamId, query } = params;
+ const { teamId, query } = filters;
const mode = prisma.getQueryMode();
const where: Prisma.UserWhereInput = {
@@ -67,49 +75,19 @@ export async function getUsers(
],
},
}),
+ deletedAt: null,
};
- const [pageFilters, getParameters] = prisma.getPageFilters({
- orderBy: 'createdAt',
- sortDescending: true,
- ...params,
- });
-
- const users = await prisma.client.user
- .findMany({
- where: {
- ...where,
- deletedAt: null,
- },
- ...pageFilters,
- ...(options?.include && { include: options.include }),
- })
- .then((a: { [x: string]: any; password: any }[]) => {
- return a.map(({ password, ...rest }) => rest);
- });
-
- const count = await prisma.client.user.count({
- where: {
- ...where,
- deletedAt: null,
- },
- });
-
- return { data: users as any, count, ...getParameters };
-}
-
-export async function getUsersByTeamId(teamId: string, filter?: UserSearchFilter) {
- return getUsers(
- { teamId, ...filter },
+ return prisma.pagedQuery(
+ 'user',
{
- include: {
- teamUser: {
- select: {
- teamId: true,
- role: true,
- },
- },
- },
+ ...criteria,
+ where,
+ },
+ {
+ orderBy: 'createdAt',
+ sortDescending: true,
+ ...filters,
},
);
}
diff --git a/src/queries/admin/website.ts b/src/queries/admin/website.ts
index 7789a6ec..3024caf1 100644
--- a/src/queries/admin/website.ts
+++ b/src/queries/admin/website.ts
@@ -2,29 +2,37 @@ import { Prisma, Website } from '@prisma/client';
import cache from 'lib/cache';
import prisma from 'lib/prisma';
import { FilterResult, WebsiteSearchFilter } from 'lib/types';
+import WebsiteFindManyArgs = Prisma.WebsiteFindManyArgs;
-async function getWebsite(where: Prisma.WebsiteWhereUniqueInput): Promise {
- return prisma.client.website.findUnique({
- where,
+async function findWebsite(criteria: Prisma.WebsiteFindManyArgs): Promise {
+ return prisma.client.website.findUnique(criteria);
+}
+
+export async function getWebsite(websiteId: string) {
+ return findWebsite({
+ where: {
+ id: websiteId,
+ },
});
}
-export async function getWebsiteById(id: string) {
- return getWebsite({ id });
-}
-
-export async function getWebsiteByShareId(shareId: string) {
- return getWebsite({ shareId });
+export async function getSharedWebsite(shareId: string) {
+ return findWebsite({
+ where: {
+ shareId,
+ },
+ });
}
export async function getWebsites(
+ criteria: WebsiteFindManyArgs,
filters: WebsiteSearchFilter,
- options?: { include?: Prisma.WebsiteInclude },
): Promise> {
const { userId, teamId, query } = filters;
const mode = prisma.getQueryMode();
const where: Prisma.WebsiteWhereInput = {
+ ...criteria.where,
AND: [
{
OR: [
@@ -47,34 +55,29 @@ export async function getWebsites(
: [],
},
],
+ deletedAt: null,
};
- const [pageFilters, getParameters] = prisma.getPageFilters({
- orderBy: 'name',
- ...filters,
- });
-
- const websites = await prisma.client.website.findMany({
- where: {
- ...where,
- deletedAt: null,
- },
- ...pageFilters,
- ...(options?.include && { include: options.include }),
- });
-
- const count = await prisma.client.website.count({ where: { ...where, deletedAt: null } });
-
- return { data: websites, count, ...getParameters };
+ return prisma.pagedQuery('website', { where }, filters);
}
-export async function getWebsitesByUserId(
+export async function getAllWebsites(userId: string) {
+ return prisma.client.website.findMany({
+ where: {
+ userId,
+ },
+ });
+}
+
+export async function getUserWebsites(
userId: string,
filters?: WebsiteSearchFilter,
): Promise> {
return getWebsites(
- { userId, ...filters },
{
+ where: {
+ userId,
+ },
include: {
user: {
select: {
@@ -84,19 +87,22 @@ export async function getWebsitesByUserId(
},
},
},
+ {
+ orderBy: 'name',
+ ...filters,
+ },
);
}
-export async function getWebsitesByTeamId(
+export async function getTeamWebsites(
teamId: string,
filters?: WebsiteSearchFilter,
): Promise> {
return getWebsites(
{
- teamId,
- ...filters,
- },
- {
+ where: {
+ teamId,
+ },
include: {
user: {
select: {
@@ -106,80 +112,10 @@ export async function getWebsitesByTeamId(
},
},
},
+ filters,
);
}
-export async function getUserWebsites(
- userId: string,
- options?: { includeTeams: boolean },
-): Promise {
- const { rawQuery } = prisma;
-
- if (options?.includeTeams) {
- const websites = await rawQuery(
- `
- select
- website_id as "id",
- name,
- domain,
- share_id as "shareId",
- reset_at as "resetAt",
- user_id as "userId",
- created_at as "createdAt",
- updated_at as "updatedAt",
- deleted_at as "deletedAt",
- null as "teamId",
- null as "teamName"
- from website
- where user_id = {{userId::uuid}}
- and deleted_at is null
- union
- select
- w.website_id as "id",
- w.name,
- w.domain,
- w.share_id as "shareId",
- w.reset_at as "resetAt",
- w.user_id as "userId",
- w.created_at as "createdAt",
- w.updated_at as "updatedAt",
- w.deleted_at as "deletedAt",
- t.team_id as "teamId",
- t.name as "teamName"
- from website w
- inner join team_website tw
- on tw.website_id = w.website_id
- inner join team t
- on t.team_id = tw.team_id
- inner join team_user tu
- on tu.team_id = tw.team_id
- where tu.user_id = {{userId::uuid}}
- and w.deleted_at is null
- `,
- { userId },
- );
-
- return websites.reduce((arr, item) => {
- if (!arr.find(({ id }) => id === item.id)) {
- return arr.concat(item);
- }
- return arr;
- }, []);
- }
-
- return prisma.client.website.findMany({
- where: {
- userId,
- deletedAt: null,
- },
- orderBy: [
- {
- name: 'asc',
- },
- ],
- });
-}
-
export async function createWebsite(
data: Prisma.WebsiteCreateInput | Prisma.WebsiteUncheckedCreateInput,
): Promise {