mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-17 00:44:23 +02:00
Use skip/take cursors instead of page number
This commit is contained in:
@@ -16,11 +16,11 @@ const getAlbumArtists = async (req: Request, res: Response) => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { limit, page, serverFolderIds } = req.query;
|
const { take, skip, serverFolderIds } = req.query;
|
||||||
const data = await albumArtistsService.findMany(req, {
|
const data = await albumArtistsService.findMany(req, {
|
||||||
limit: Number(limit),
|
|
||||||
page: Number(page),
|
|
||||||
serverFolderIds: String(serverFolderIds),
|
serverFolderIds: String(serverFolderIds),
|
||||||
|
skip: Number(skip),
|
||||||
|
take: Number(take),
|
||||||
user: req.auth,
|
user: req.auth,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,15 +38,16 @@ const getAlbums = async (req: Request, res: Response) => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { limit, page, serverFolderIds, serverUrls, sortBy, orderBy } =
|
const { take, serverFolderIds, serverUrls, sortBy, orderBy, skip } =
|
||||||
req.query;
|
req.query;
|
||||||
|
|
||||||
const data = await albumsService.findMany(req, {
|
const data = await albumsService.findMany(req, {
|
||||||
limit: Number(limit),
|
|
||||||
orderBy: orderBy as SortOrder,
|
orderBy: orderBy as SortOrder,
|
||||||
page: Number(page),
|
|
||||||
serverFolderIds: serverFolderIds && String(serverFolderIds),
|
serverFolderIds: serverFolderIds && String(serverFolderIds),
|
||||||
serverUrls: serverUrls && String(serverUrls),
|
serverUrls: serverUrls && String(serverUrls),
|
||||||
|
skip: Number(skip),
|
||||||
sortBy: sortBy as AlbumSort,
|
sortBy: sortBy as AlbumSort,
|
||||||
|
take: Number(take),
|
||||||
user: req.auth,
|
user: req.auth,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ const getArtists = async (req: Request, res: Response) => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { limit, page, serverFolderIds } = req.query;
|
const { take, skip, serverFolderIds } = req.query;
|
||||||
const data = await artistsService.findMany(req, {
|
const data = await artistsService.findMany(req, {
|
||||||
limit: Number(limit),
|
|
||||||
page: Number(page),
|
|
||||||
serverFolderIds: String(serverFolderIds),
|
serverFolderIds: String(serverFolderIds),
|
||||||
|
skip: Number(skip),
|
||||||
|
take: Number(take),
|
||||||
user: req.auth,
|
user: req.auth,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ const getSongs = async (req: Request, res: Response) => {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { limit, page, serverFolderIds } = req.query;
|
const { take, skip, serverFolderIds } = req.query;
|
||||||
|
|
||||||
const data = await songsService.findMany(req, {
|
const data = await songsService.findMany(req, {
|
||||||
limit: Number(limit),
|
|
||||||
page: Number(page),
|
|
||||||
serverFolderIds: String(serverFolderIds),
|
serverFolderIds: String(serverFolderIds),
|
||||||
|
skip: Number(skip),
|
||||||
|
take: Number(take),
|
||||||
user: req.auth,
|
user: req.auth,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { songHelpers } from './songs.helpers';
|
|||||||
export enum AlbumSort {
|
export enum AlbumSort {
|
||||||
DATE_ADDED = 'date_added',
|
DATE_ADDED = 'date_added',
|
||||||
DATE_ADDED_REMOTE = 'date_added_remote',
|
DATE_ADDED_REMOTE = 'date_added_remote',
|
||||||
DATE_PLAYED = 'date_played',
|
|
||||||
DATE_RELEASED = 'date_released',
|
DATE_RELEASED = 'date_released',
|
||||||
RANDOM = 'random',
|
RANDOM = 'random',
|
||||||
RATING = 'rating',
|
RATING = 'rating',
|
||||||
|
|||||||
@@ -14,7 +14,11 @@ export const errorHandler = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (err.message) {
|
if (err.message) {
|
||||||
message = isJsonString(err.message) ? JSON.parse(err.message) : err.message;
|
message = isJsonString(err.message)
|
||||||
|
? Array.isArray(JSON.parse(err.message))
|
||||||
|
? JSON.parse(err.message)[0].message // Handles errors sent from zod preprocess
|
||||||
|
: JSON.parse(err.message)
|
||||||
|
: err.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(err.statusCode || 500).json({
|
res.status(err.statusCode || 500).json({
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const findMany = async (
|
|||||||
req: Request,
|
req: Request,
|
||||||
options: { serverFolderIds: string; user: User } & OffsetPagination
|
options: { serverFolderIds: string; user: User } & OffsetPagination
|
||||||
) => {
|
) => {
|
||||||
const { user, limit, page, serverFolderIds: rServerFolderIds } = options;
|
const { user, take, serverFolderIds: rServerFolderIds, skip } = options;
|
||||||
const serverFolderIds = splitNumberString(rServerFolderIds);
|
const serverFolderIds = splitNumberString(rServerFolderIds);
|
||||||
|
|
||||||
if (!(await folderPermissions(serverFolderIds!, user))) {
|
if (!(await folderPermissions(serverFolderIds!, user))) {
|
||||||
@@ -52,23 +52,21 @@ const findMany = async (
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const startIndex = limit * page;
|
|
||||||
const totalEntries = await prisma.albumArtist.count({
|
const totalEntries = await prisma.albumArtist.count({
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
});
|
});
|
||||||
const albumArtists = await prisma.albumArtist.findMany({
|
const albumArtists = await prisma.albumArtist.findMany({
|
||||||
include: { genres: true },
|
include: { genres: true },
|
||||||
skip: startIndex,
|
skip,
|
||||||
take: limit,
|
take,
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
});
|
});
|
||||||
|
|
||||||
return ApiSuccess.ok({
|
return ApiSuccess.ok({
|
||||||
data: albumArtists,
|
data: albumArtists,
|
||||||
paginationItems: {
|
paginationItems: {
|
||||||
limit,
|
skip,
|
||||||
page,
|
take,
|
||||||
startIndex,
|
|
||||||
totalEntries,
|
totalEntries,
|
||||||
url: req.originalUrl,
|
url: req.originalUrl,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ const findMany = async (
|
|||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
user,
|
user,
|
||||||
limit,
|
take,
|
||||||
page,
|
|
||||||
serverFolderIds: rServerFolderIds,
|
serverFolderIds: rServerFolderIds,
|
||||||
serverUrls,
|
serverUrls,
|
||||||
|
skip,
|
||||||
sortBy,
|
sortBy,
|
||||||
orderBy,
|
orderBy,
|
||||||
} = options;
|
} = options;
|
||||||
@@ -75,7 +75,6 @@ const findMany = async (
|
|||||||
serverFolderIds!
|
serverFolderIds!
|
||||||
);
|
);
|
||||||
|
|
||||||
const startIndex = limit * page;
|
|
||||||
let totalEntries = 0;
|
let totalEntries = 0;
|
||||||
let albums: Album[];
|
let albums: Album[];
|
||||||
|
|
||||||
@@ -94,8 +93,8 @@ const findMany = async (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
orderBy: { value: orderBy },
|
orderBy: { value: orderBy },
|
||||||
skip: startIndex,
|
skip,
|
||||||
take: limit,
|
take,
|
||||||
where: {
|
where: {
|
||||||
album: { OR: serverFoldersFilter },
|
album: { OR: serverFoldersFilter },
|
||||||
user: { id: user.id },
|
user: { id: user.id },
|
||||||
@@ -113,8 +112,8 @@ const findMany = async (
|
|||||||
prisma.album.findMany({
|
prisma.album.findMany({
|
||||||
include: { ...albumHelpers.include({ serverUrls, songs: false }) },
|
include: { ...albumHelpers.include({ serverUrls, songs: false }) },
|
||||||
orderBy: [{ ...albumHelpers.sort(sortBy, orderBy) }],
|
orderBy: [{ ...albumHelpers.sort(sortBy, orderBy) }],
|
||||||
skip: startIndex,
|
skip,
|
||||||
take: limit,
|
take,
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@@ -126,9 +125,8 @@ const findMany = async (
|
|||||||
return ApiSuccess.ok({
|
return ApiSuccess.ok({
|
||||||
data: toRes.albums(albums, user),
|
data: toRes.albums(albums, user),
|
||||||
paginationItems: {
|
paginationItems: {
|
||||||
limit,
|
skip,
|
||||||
page,
|
take,
|
||||||
startIndex,
|
|
||||||
totalEntries,
|
totalEntries,
|
||||||
url: req.originalUrl,
|
url: req.originalUrl,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const findMany = async (
|
|||||||
req: Request,
|
req: Request,
|
||||||
options: { serverFolderIds: string; user: User } & OffsetPagination
|
options: { serverFolderIds: string; user: User } & OffsetPagination
|
||||||
) => {
|
) => {
|
||||||
const { user, limit, page, serverFolderIds: rServerFolderIds } = options;
|
const { user, skip, take, serverFolderIds: rServerFolderIds } = options;
|
||||||
const serverFolderIds = splitNumberString(rServerFolderIds);
|
const serverFolderIds = splitNumberString(rServerFolderIds);
|
||||||
|
|
||||||
if (!(await folderPermissions(serverFolderIds!, user))) {
|
if (!(await folderPermissions(serverFolderIds!, user))) {
|
||||||
@@ -52,23 +52,21 @@ const findMany = async (
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const startIndex = limit * page;
|
|
||||||
const totalEntries = await prisma.artist.count({
|
const totalEntries = await prisma.artist.count({
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
});
|
});
|
||||||
const artists = await prisma.artist.findMany({
|
const artists = await prisma.artist.findMany({
|
||||||
include: { genres: true },
|
include: { genres: true },
|
||||||
skip: startIndex,
|
skip,
|
||||||
take: limit,
|
take,
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
});
|
});
|
||||||
|
|
||||||
return ApiSuccess.ok({
|
return ApiSuccess.ok({
|
||||||
data: artists,
|
data: artists,
|
||||||
paginationItems: {
|
paginationItems: {
|
||||||
limit,
|
skip,
|
||||||
page,
|
take,
|
||||||
startIndex,
|
|
||||||
totalEntries,
|
totalEntries,
|
||||||
url: req.originalUrl,
|
url: req.originalUrl,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { prisma } from '../lib';
|
import { prisma } from '../lib';
|
||||||
import { OffsetPagination, User } from '../types/types';
|
import { User } from '../types/types';
|
||||||
import {
|
import {
|
||||||
ApiError,
|
ApiError,
|
||||||
ApiSuccess,
|
ApiSuccess,
|
||||||
@@ -52,8 +52,8 @@ const findMany = async (
|
|||||||
artistIds: rawArtistIds,
|
artistIds: rawArtistIds,
|
||||||
songIds: rawSongIds,
|
songIds: rawSongIds,
|
||||||
user,
|
user,
|
||||||
limit,
|
skip,
|
||||||
page,
|
take,
|
||||||
serverFolderIds: rServerFolderIds,
|
serverFolderIds: rServerFolderIds,
|
||||||
} = options;
|
} = options;
|
||||||
const serverFolderIds = splitNumberString(rServerFolderIds);
|
const serverFolderIds = splitNumberString(rServerFolderIds);
|
||||||
@@ -75,8 +75,6 @@ const findMany = async (
|
|||||||
serverFolders: { some: { id: { in: serverFolderIds } } },
|
serverFolders: { some: { id: { in: serverFolderIds } } },
|
||||||
};
|
};
|
||||||
|
|
||||||
const startIndex = limit * page;
|
|
||||||
|
|
||||||
const [totalEntries, songs] = await prisma.$transaction([
|
const [totalEntries, songs] = await prisma.$transaction([
|
||||||
prisma.song.count({
|
prisma.song.count({
|
||||||
where: {
|
where: {
|
||||||
@@ -96,8 +94,8 @@ const findMany = async (
|
|||||||
images: true,
|
images: true,
|
||||||
serverFolders: { include: { server: true } },
|
serverFolders: { include: { server: true } },
|
||||||
},
|
},
|
||||||
skip: startIndex,
|
skip,
|
||||||
take: limit,
|
take,
|
||||||
where: { OR: serverFoldersFilter },
|
where: { OR: serverFoldersFilter },
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@@ -105,9 +103,8 @@ const findMany = async (
|
|||||||
return ApiSuccess.ok({
|
return ApiSuccess.ok({
|
||||||
data: songs,
|
data: songs,
|
||||||
paginationItems: {
|
paginationItems: {
|
||||||
limit,
|
skip,
|
||||||
page,
|
take,
|
||||||
startIndex,
|
|
||||||
totalEntries,
|
totalEntries,
|
||||||
url: req.originalUrl,
|
url: req.originalUrl,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ export type Task = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type OffsetPagination = {
|
export type OffsetPagination = {
|
||||||
limit: number;
|
skip: number;
|
||||||
page: number;
|
take: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PaginationResponse = {
|
export type PaginationResponse = {
|
||||||
@@ -131,9 +131,8 @@ export type SuccessResponse = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type PaginationItems = {
|
export type PaginationItems = {
|
||||||
limit: number;
|
skip: number;
|
||||||
page: number;
|
take: number;
|
||||||
startIndex: number;
|
|
||||||
totalEntries: number;
|
totalEntries: number;
|
||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { PaginationItems } from '../types/types';
|
import { PaginationItems } from '../types/types';
|
||||||
|
|
||||||
const getPaginationUrl = (url: string, action: 'next' | 'prev') => {
|
const getPaginationUrl = (
|
||||||
const currentPageRegex = url.match(/page=(\d+)/gm);
|
url: string,
|
||||||
|
skip: number,
|
||||||
if (currentPageRegex) {
|
take: number,
|
||||||
const currentPage = Number(currentPageRegex[0].split('=')[1]);
|
action: 'next' | 'prev'
|
||||||
const newPage = action === 'next' ? currentPage + 1 : currentPage - 1;
|
) => {
|
||||||
const normalizedUrl = process.env.APP_BASE_URL?.replace(/\/$/, '');
|
if (action === 'next') {
|
||||||
|
return url.replace(/skip=(\d+)/gm, `skip=${skip + take}`);
|
||||||
return `${normalizedUrl}${url.replace(/page=\d+/gm, `page=${newPage}`)}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return url.replace(/skip=(\d+)/gm, `skip=${skip - take}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSuccessResponse = (options: {
|
export const getSuccessResponse = (options: {
|
||||||
@@ -24,15 +23,15 @@ export const getSuccessResponse = (options: {
|
|||||||
let pagination;
|
let pagination;
|
||||||
|
|
||||||
if (paginationItems) {
|
if (paginationItems) {
|
||||||
const { startIndex, totalEntries, limit, url, page } = paginationItems;
|
const { skip, totalEntries, take, url } = paginationItems;
|
||||||
const hasPrevPage = startIndex - limit >= 0;
|
|
||||||
const hasNextPage = startIndex + limit <= totalEntries;
|
const hasPrevPage = skip - take >= 0;
|
||||||
|
const hasNextPage = skip + take <= totalEntries;
|
||||||
|
|
||||||
pagination = {
|
pagination = {
|
||||||
currentPage: page,
|
nextPage: hasNextPage ? getPaginationUrl(url, skip, take, 'next') : null,
|
||||||
nextPage: hasNextPage ? getPaginationUrl(url, 'next') : null,
|
prevPage: hasPrevPage ? getPaginationUrl(url, skip, take, 'prev') : null,
|
||||||
prevPage: hasPrevPage ? getPaginationUrl(url, 'prev') : null,
|
skip,
|
||||||
startIndex,
|
|
||||||
totalEntries,
|
totalEntries,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ export * from './split-text-string';
|
|||||||
export * from './folder-permissions';
|
export * from './folder-permissions';
|
||||||
export * from './is-array-equal';
|
export * from './is-array-equal';
|
||||||
export * from './is-json-string';
|
export * from './is-json-string';
|
||||||
export * from './validate-request';
|
|
||||||
export * from './unique-array';
|
export * from './unique-array';
|
||||||
export * from './zod-validation';
|
export * from './zod-validation';
|
||||||
export * from './get-image-url';
|
export * from './get-image-url';
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
// Taken from zod-express-middleware: https://github.com/Aquila169/zod-express-middleware
|
|
||||||
|
|
||||||
import { ZodError, ZodSchema } from 'zod';
|
|
||||||
import { ApiError } from './api-error';
|
|
||||||
|
|
||||||
type RequestValidation<TParams, TQuery, TBody> = {
|
|
||||||
body?: ZodSchema<TBody>;
|
|
||||||
params?: ZodSchema<TParams>;
|
|
||||||
query?: ZodSchema<TQuery>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ErrorListItem = {
|
|
||||||
errors: ZodError<any>;
|
|
||||||
type: 'Query' | 'Params' | 'Body';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const validateRequest = (
|
|
||||||
req: any,
|
|
||||||
schemas: RequestValidation<any, any, any>
|
|
||||||
) => {
|
|
||||||
const { params, query, body } = schemas;
|
|
||||||
const errors: Array<ErrorListItem> = [];
|
|
||||||
|
|
||||||
if (params) {
|
|
||||||
const parsed = params.safeParse(req.params);
|
|
||||||
if (!parsed.success) {
|
|
||||||
errors.push({ errors: parsed.error, type: 'Params' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query) {
|
|
||||||
const parsed = query.safeParse(req.query);
|
|
||||||
if (!parsed.success) {
|
|
||||||
errors.push({ errors: parsed.error, type: 'Query' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body) {
|
|
||||||
const parsed = body.safeParse(req.body);
|
|
||||||
if (!parsed.success) {
|
|
||||||
errors.push({ errors: parsed.error, type: 'Body' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors.length > 0) {
|
|
||||||
const message = JSON.stringify(
|
|
||||||
[
|
|
||||||
`[${errors[0].type}]`,
|
|
||||||
`[${errors[0].errors.issues[0].path[0]}]`,
|
|
||||||
errors[0].errors.issues[0].message,
|
|
||||||
].join(' ')
|
|
||||||
);
|
|
||||||
|
|
||||||
throw ApiError.badRequest(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,11 +1,97 @@
|
|||||||
import { z } from 'zod';
|
// Taken from zod-express-middleware: https://github.com/Aquila169/zod-express-middleware
|
||||||
|
import { z, ZodError, ZodSchema } from 'zod';
|
||||||
|
import { ApiError } from './api-error';
|
||||||
|
|
||||||
|
export enum ValidationType {
|
||||||
|
BODY = 'Body',
|
||||||
|
PARAMS = 'Params',
|
||||||
|
QUERY = 'Query',
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestValidation<TParams, TQuery, TBody> = {
|
||||||
|
body?: ZodSchema<TBody>;
|
||||||
|
params?: ZodSchema<TParams>;
|
||||||
|
query?: ZodSchema<TQuery>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ErrorListItem = {
|
||||||
|
errors: ZodError<any>;
|
||||||
|
type: ValidationType;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const validateRequest = (
|
||||||
|
req: any,
|
||||||
|
schemas: RequestValidation<any, any, any>
|
||||||
|
) => {
|
||||||
|
const { params, query, body } = schemas;
|
||||||
|
const errors: Array<ErrorListItem> = [];
|
||||||
|
|
||||||
|
if (params) {
|
||||||
|
const parsed = params.safeParse(req.params);
|
||||||
|
if (!parsed.success) {
|
||||||
|
errors.push({ errors: parsed.error, type: ValidationType.PARAMS });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
const parsed = query.safeParse(req.query);
|
||||||
|
if (!parsed.success) {
|
||||||
|
errors.push({ errors: parsed.error, type: ValidationType.QUERY });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body) {
|
||||||
|
const parsed = body.safeParse(req.body);
|
||||||
|
if (!parsed.success) {
|
||||||
|
errors.push({ errors: parsed.error, type: ValidationType.BODY });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length > 0) {
|
||||||
|
const message = JSON.stringify(
|
||||||
|
[
|
||||||
|
`(${errors[0].type})`,
|
||||||
|
`[${errors[0].errors.issues[0].path[0]}]`,
|
||||||
|
errors[0].errors.issues[0].message,
|
||||||
|
].join(' ')
|
||||||
|
);
|
||||||
|
|
||||||
|
throw ApiError.badRequest(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const requiredErrorMessage = (
|
||||||
|
type: 'Query' | 'Body' | 'Params',
|
||||||
|
key: string
|
||||||
|
) => {
|
||||||
|
return `(${type}) [${key}] Required`;
|
||||||
|
};
|
||||||
|
|
||||||
export const paginationValidation = {
|
export const paginationValidation = {
|
||||||
limit: z.preprocess(
|
skip: z.preprocess(
|
||||||
(a) => parseInt(z.string().parse(a), 10),
|
(a) =>
|
||||||
z.number().min(0).max(1000)
|
parseInt(
|
||||||
|
z
|
||||||
|
.string({
|
||||||
|
required_error: requiredErrorMessage(ValidationType.QUERY, 'skip'),
|
||||||
|
})
|
||||||
|
.parse(a),
|
||||||
|
10
|
||||||
|
),
|
||||||
|
z.number().min(0, { message: 'Must have skip' })
|
||||||
|
),
|
||||||
|
take: z.preprocess(
|
||||||
|
(a) =>
|
||||||
|
parseInt(
|
||||||
|
z
|
||||||
|
.string({
|
||||||
|
required_error: requiredErrorMessage(ValidationType.QUERY, 'take'),
|
||||||
|
})
|
||||||
|
.parse(a),
|
||||||
|
10
|
||||||
|
),
|
||||||
|
z.number().min(0)
|
||||||
),
|
),
|
||||||
page: z.preprocess((a) => parseInt(z.string().parse(a), 10), z.number()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const idValidation = {
|
export const idValidation = {
|
||||||
|
|||||||
Reference in New Issue
Block a user