mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-08 13:00:13 +02:00
Move server directory outside of frontend src
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
export class ApiError extends Error {
|
||||
message: string;
|
||||
statusCode: number;
|
||||
|
||||
constructor(options: { message: string; statusCode: number }) {
|
||||
super(options.message);
|
||||
this.message = options.message;
|
||||
this.statusCode = options.statusCode;
|
||||
}
|
||||
|
||||
static badRequest(message?: string) {
|
||||
return new ApiError({
|
||||
message: message || 'Bad request.',
|
||||
statusCode: 400,
|
||||
});
|
||||
}
|
||||
|
||||
static unauthorized(message?: string) {
|
||||
return new ApiError({
|
||||
message: message || 'Unauthorized.',
|
||||
statusCode: 401,
|
||||
});
|
||||
}
|
||||
|
||||
static forbidden(message?: string) {
|
||||
return new ApiError({ message: message || 'Forbidden.', statusCode: 403 });
|
||||
}
|
||||
|
||||
static notFound(message?: string) {
|
||||
return new ApiError({ message: message || 'Not found.', statusCode: 404 });
|
||||
}
|
||||
|
||||
static conflict(message?: string) {
|
||||
return new ApiError({ message: message || 'Conflict.', statusCode: 409 });
|
||||
}
|
||||
|
||||
static gone(message?: string) {
|
||||
return new ApiError({ message: message || 'Gone.', statusCode: 410 });
|
||||
}
|
||||
|
||||
static internal(message?: string) {
|
||||
return new ApiError({
|
||||
message: message || 'Internal error.',
|
||||
statusCode: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { PaginationItems, SuccessResponse } from '../types/types';
|
||||
|
||||
export class ApiSuccess {
|
||||
data: any;
|
||||
statusCode: number;
|
||||
paginationItems?: PaginationItems;
|
||||
|
||||
constructor(options: {
|
||||
data: any;
|
||||
paginationItems?: PaginationItems;
|
||||
statusCode: number;
|
||||
}) {
|
||||
this.data = options.data;
|
||||
this.statusCode = options.statusCode;
|
||||
this.paginationItems = options.paginationItems;
|
||||
}
|
||||
|
||||
static ok({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({
|
||||
data,
|
||||
paginationItems,
|
||||
statusCode: 200,
|
||||
});
|
||||
}
|
||||
|
||||
static created({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({ data, paginationItems, statusCode: 201 });
|
||||
}
|
||||
|
||||
static accepted({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({ data, paginationItems, statusCode: 202 });
|
||||
}
|
||||
|
||||
static noContent({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({ data, paginationItems, statusCode: 204 });
|
||||
}
|
||||
|
||||
static resetContent({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({ data, paginationItems, statusCode: 205 });
|
||||
}
|
||||
|
||||
static partialContent({ data, paginationItems }: SuccessResponse) {
|
||||
return new ApiSuccess({ data, paginationItems, statusCode: 206 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { User } from '@prisma/client';
|
||||
import { prisma } from '../lib';
|
||||
|
||||
export enum Roles {
|
||||
NONE = 0,
|
||||
GUEST = 1,
|
||||
USER = 2,
|
||||
ADMIN = 4,
|
||||
SUPERADMIN = 8,
|
||||
}
|
||||
|
||||
export enum FolderRoles {
|
||||
NONE = 0,
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
ADMIN = 4,
|
||||
}
|
||||
|
||||
export const folderPermissions = async (serverFolderIds: any[], user: User) => {
|
||||
if (user.isAdmin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const serverFoldersWithAccess = await prisma.serverFolder.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
AND: [
|
||||
{
|
||||
serverFolderPermissions: {
|
||||
some: { userId: { equals: user.id } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const serverFoldersWithAccessIds = serverFoldersWithAccess.map(
|
||||
(serverFolder) => serverFolder.id
|
||||
);
|
||||
|
||||
const hasAccess = serverFolderIds.every((id) =>
|
||||
serverFoldersWithAccessIds.includes(id)
|
||||
);
|
||||
|
||||
return hasAccess;
|
||||
};
|
||||
|
||||
export const getFolderPermissions = async (user: User) => {
|
||||
if (user.isAdmin) {
|
||||
const serverFoldersWithAccess = await prisma.serverFolder.findMany();
|
||||
|
||||
const serverFoldersWithAccessIds = serverFoldersWithAccess.map(
|
||||
(serverFolder) => serverFolder.id
|
||||
);
|
||||
|
||||
return serverFoldersWithAccessIds;
|
||||
}
|
||||
|
||||
const serverFoldersWithAccess = await prisma.serverFolder.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
AND: [
|
||||
{
|
||||
serverFolderPermissions: {
|
||||
some: { userId: { equals: user.id } },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const serverFoldersWithAccessIds = serverFoldersWithAccess.map(
|
||||
(serverFolder) => serverFolder.id
|
||||
);
|
||||
|
||||
return serverFoldersWithAccessIds;
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import { PaginationItems } from '../types/types';
|
||||
|
||||
const getPaginationUrl = (
|
||||
url: string,
|
||||
skip: number,
|
||||
take: number,
|
||||
action: 'next' | 'prev'
|
||||
) => {
|
||||
if (action === 'next') {
|
||||
return url.replace(/skip=(\d+)/gm, `skip=${skip + take}`);
|
||||
}
|
||||
|
||||
return url.replace(/skip=(\d+)/gm, `skip=${skip - take}`);
|
||||
};
|
||||
|
||||
export const getSuccessResponse = (options: {
|
||||
data: any;
|
||||
paginationItems?: PaginationItems;
|
||||
statusCode: number;
|
||||
}) => {
|
||||
const { statusCode, data, paginationItems } = options;
|
||||
|
||||
let pagination;
|
||||
|
||||
if (paginationItems) {
|
||||
const { skip, totalEntries, take, url } = paginationItems;
|
||||
|
||||
const hasPrevPage = skip - take >= 0;
|
||||
const hasNextPage = skip + take <= totalEntries;
|
||||
|
||||
pagination = {
|
||||
nextPage: hasNextPage ? getPaginationUrl(url, skip, take, 'next') : null,
|
||||
prevPage: hasPrevPage ? getPaginationUrl(url, skip, take, 'prev') : null,
|
||||
skip,
|
||||
totalEntries,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
pagination,
|
||||
response: 'Success',
|
||||
statusCode,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const groupByProperty = (object: any, property: string) => {
|
||||
return object.reduce((groups: any, item: any) => {
|
||||
const group = groups[item[property]] || [];
|
||||
group.push(item);
|
||||
groups[item[property]] = group;
|
||||
return groups;
|
||||
}, {});
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export * from './api-error';
|
||||
export * from './api-success';
|
||||
export * from './get-success-response';
|
||||
export * from './group-by-property';
|
||||
export * from './split-number-string';
|
||||
export * from './split-text-string';
|
||||
export * from './folder-permissions';
|
||||
export * from './is-array-equal';
|
||||
export * from './is-json-string';
|
||||
export * from './unique-array';
|
||||
export * from './random-string';
|
||||
@@ -0,0 +1,13 @@
|
||||
export const validateArrayEqual = (array1: any[], array2: any[]) => {
|
||||
if (array1.length === array2.length) {
|
||||
return array1.every((element) => {
|
||||
if (array2.includes(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const isJsonString = (string: string) => {
|
||||
try {
|
||||
JSON.parse(string);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export const randomString = (length: number) => {
|
||||
const charSet =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let string = '';
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
const randomPoz = Math.floor(Math.random() * charSet.length);
|
||||
string += charSet.substring(randomPoz, randomPoz + 1);
|
||||
}
|
||||
return string;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const splitNumberString = (string?: string, delimiter = ',') => {
|
||||
if (!string) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return string.split(delimiter).map((s: string) => {
|
||||
return Number(s);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export const splitTextString = (string: string, delimiter = ',') => {
|
||||
return string.split(delimiter).map((s: string) => {
|
||||
return String(s);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export const uniqueArray = (value: any, index: any, self: any) => {
|
||||
return self.indexOf(value) === index && value !== undefined;
|
||||
};
|
||||
Reference in New Issue
Block a user