mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-15 04:51:06 +02:00
Move server directory outside of frontend src
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { AuthUser } from '@/middleware';
|
||||
import { SortOrder } from '@/types/types';
|
||||
import { songHelpers } from '@helpers/songs.helpers';
|
||||
|
||||
export enum AlbumSort {
|
||||
DATE_ADDED = 'added',
|
||||
DATE_ADDED_REMOTE = 'addedRemote',
|
||||
DATE_RELEASED = 'released',
|
||||
DATE_RELEASED_YEAR = 'year',
|
||||
FAVORITE = 'favorite',
|
||||
NAME = 'name',
|
||||
RANDOM = 'random',
|
||||
RATING = 'rating',
|
||||
}
|
||||
|
||||
const include = (options: { songs?: boolean; user?: AuthUser }) => {
|
||||
// Prisma.AlbumInclude
|
||||
const props = {
|
||||
_count: {
|
||||
select: {
|
||||
favorites: true,
|
||||
songs: true,
|
||||
},
|
||||
},
|
||||
albumArtists: true,
|
||||
artists: true,
|
||||
favorites: { where: { userId: options.user?.id } },
|
||||
genres: true,
|
||||
images: true,
|
||||
ratings: {
|
||||
where: {
|
||||
userId: options.user?.id,
|
||||
},
|
||||
},
|
||||
server: true,
|
||||
serverFolders: true,
|
||||
songs: options?.songs && songHelpers.findMany(),
|
||||
};
|
||||
|
||||
return props;
|
||||
};
|
||||
|
||||
const sort = (sortBy: AlbumSort, orderBy: SortOrder) => {
|
||||
let order;
|
||||
|
||||
switch (sortBy) {
|
||||
case AlbumSort.NAME:
|
||||
order = { name: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.DATE_ADDED:
|
||||
order = { createdAt: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.DATE_ADDED_REMOTE:
|
||||
order = { remoteCreatedAt: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.DATE_RELEASED:
|
||||
order = { releaseDate: orderBy, year: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.DATE_RELEASED_YEAR:
|
||||
order = { releaseYear: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.RATING:
|
||||
order = { rating: orderBy };
|
||||
break;
|
||||
|
||||
case AlbumSort.FAVORITE:
|
||||
order = { favorite: orderBy };
|
||||
break;
|
||||
|
||||
default:
|
||||
order = { title: orderBy };
|
||||
break;
|
||||
}
|
||||
|
||||
return order;
|
||||
};
|
||||
|
||||
export const albumHelpers = {
|
||||
include,
|
||||
sort,
|
||||
};
|
||||
@@ -0,0 +1,520 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import {
|
||||
Album,
|
||||
AlbumArtist,
|
||||
AlbumArtistRating,
|
||||
AlbumRating,
|
||||
Artist,
|
||||
ArtistRating,
|
||||
External,
|
||||
Genre,
|
||||
Image,
|
||||
ImageType,
|
||||
Server,
|
||||
ServerFolder,
|
||||
ServerFolderPermission,
|
||||
ServerPermission,
|
||||
ServerType,
|
||||
ServerUrl,
|
||||
Song,
|
||||
SongRating,
|
||||
User,
|
||||
UserServerUrl,
|
||||
} from '@prisma/client';
|
||||
|
||||
const getSubsonicStreamUrl = (
|
||||
remoteId: string,
|
||||
url: string,
|
||||
token: string,
|
||||
deviceId: string
|
||||
) => {
|
||||
return (
|
||||
`${url}/rest/stream.view` +
|
||||
`?id=${remoteId}` +
|
||||
`&${token}` +
|
||||
`&v=1.13.0` +
|
||||
`&c=Feishin_${deviceId}`
|
||||
);
|
||||
};
|
||||
|
||||
const getJellyfinStreamUrl = (
|
||||
remoteId: string,
|
||||
url: string,
|
||||
token: string,
|
||||
userId: string,
|
||||
deviceId: string
|
||||
) => {
|
||||
return (
|
||||
`${url}/audio` +
|
||||
`/${remoteId}/universal` +
|
||||
`?userId=${userId}` +
|
||||
`&audioCodec=aac` +
|
||||
`&container=opus,mp3,aac,m4a,m4b,flac,wav,ogg` +
|
||||
`&transcodingContainer=ts` +
|
||||
`&transcodingProtocol=hls` +
|
||||
`&deviceId=Feishin_${deviceId}` +
|
||||
`&playSessionId=${deviceId}` +
|
||||
`&api_key=${token}`
|
||||
);
|
||||
};
|
||||
|
||||
const streamUrl = (
|
||||
type: ServerType,
|
||||
args: {
|
||||
deviceId: string;
|
||||
remoteId: string;
|
||||
token: string;
|
||||
url: string;
|
||||
userId?: string;
|
||||
}
|
||||
) => {
|
||||
if (type === ServerType.JELLYFIN) {
|
||||
return getJellyfinStreamUrl(
|
||||
args.remoteId,
|
||||
args.url,
|
||||
args.token,
|
||||
args.userId || '',
|
||||
args.deviceId
|
||||
);
|
||||
}
|
||||
return getSubsonicStreamUrl(
|
||||
args.remoteId,
|
||||
args.url,
|
||||
args.token,
|
||||
args.deviceId
|
||||
);
|
||||
};
|
||||
|
||||
const imageUrl = (
|
||||
type: ServerType,
|
||||
baseUrl: string,
|
||||
imageId: string,
|
||||
token?: string
|
||||
) => {
|
||||
if (type === ServerType.JELLYFIN) {
|
||||
return (
|
||||
`${baseUrl}/Items` +
|
||||
`/${imageId}` +
|
||||
`/Images/Primary` +
|
||||
'?fillHeight=250' +
|
||||
`&fillWidth=250` +
|
||||
'&quality=90'
|
||||
);
|
||||
}
|
||||
|
||||
if (type === ServerType.SUBSONIC || type === ServerType.NAVIDROME) {
|
||||
return (
|
||||
`${baseUrl}/rest/getCoverArt.view` +
|
||||
`?id=${imageId}` +
|
||||
`&size=250` +
|
||||
`&v=1.13.0` +
|
||||
`&c=Feishin` +
|
||||
`&${token}`
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const relatedAlbum = (item: Album) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
remoteId: item.remoteId,
|
||||
deleted: item.deleted,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
};
|
||||
|
||||
const relatedArtists = (items: Artist[]) => {
|
||||
return (
|
||||
items?.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
remoteId: item.remoteId,
|
||||
deleted: item.deleted,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
const relatedAlbumArtists = (items: AlbumArtist[]) => {
|
||||
return (
|
||||
items?.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
remoteId: item.remoteId,
|
||||
deleted: item.deleted,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
const relatedGenres = (items: Genre[]) => {
|
||||
return (
|
||||
items?.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
const relatedServerFolders = (items: ServerFolder[]) => {
|
||||
const serverFolders = items?.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
remoteId: item.remoteId,
|
||||
lastScannedAt: item.lastScannedAt,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
});
|
||||
|
||||
return serverFolders || [];
|
||||
};
|
||||
|
||||
const relatedServerUrls = (
|
||||
items: (ServerUrl & {
|
||||
userServerUrls?: UserServerUrl[];
|
||||
})[]
|
||||
) => {
|
||||
const serverUrls = items?.map((item) => {
|
||||
const userServerUrlIds = item.userServerUrls?.map(
|
||||
(userServerUrl) => userServerUrl.serverUrlId
|
||||
);
|
||||
const enabled = userServerUrlIds?.some((id) => id === item.id);
|
||||
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
url: item.url,
|
||||
enabled,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
});
|
||||
|
||||
return serverUrls || [];
|
||||
};
|
||||
|
||||
const rating = (
|
||||
items: AlbumRating[] | SongRating[] | ArtistRating[] | AlbumArtistRating[]
|
||||
) => {
|
||||
if (items.length > 0) {
|
||||
return items[0].value;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const image = (
|
||||
images: Image[],
|
||||
type: ServerType,
|
||||
imageType: ImageType,
|
||||
url: string,
|
||||
remoteId: string,
|
||||
token?: string
|
||||
) => {
|
||||
const imageRemoteUrl = images.find((i) => i.type === imageType)?.remoteUrl;
|
||||
|
||||
if (!imageRemoteUrl) return null;
|
||||
if (type === ServerType.JELLYFIN) {
|
||||
return imageUrl(type, url, remoteId);
|
||||
}
|
||||
|
||||
if (type === ServerType.SUBSONIC || type === ServerType.NAVIDROME) {
|
||||
return imageUrl(type, url, imageRemoteUrl, token);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
type DbSong = Song & DbSongInclude;
|
||||
|
||||
type DbSongInclude = {
|
||||
album: Album;
|
||||
artists: Artist[];
|
||||
externals: External[];
|
||||
genres: Genre[];
|
||||
images: Image[];
|
||||
ratings: SongRating[];
|
||||
server: Server & { serverUrls: ServerUrl[] };
|
||||
};
|
||||
|
||||
const songs = (
|
||||
items: DbSong[],
|
||||
options: {
|
||||
deviceId: string;
|
||||
imageUrl?: string;
|
||||
serverFolderId?: number;
|
||||
token: string;
|
||||
type: ServerType;
|
||||
url: string;
|
||||
userId: string;
|
||||
}
|
||||
) => {
|
||||
return (
|
||||
items?.map((item) => {
|
||||
const url = options.url ? options.url : item.server.serverUrls[0].url;
|
||||
|
||||
const stream = streamUrl(options.type, {
|
||||
deviceId: options.deviceId,
|
||||
remoteId: item.remoteId,
|
||||
token: options.token,
|
||||
url: options.url,
|
||||
userId: options.userId,
|
||||
});
|
||||
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
artistName: item.artistName,
|
||||
album: item.album && relatedAlbum(item.album),
|
||||
artists: relatedArtists(item.artists),
|
||||
bitRate: item.bitRate,
|
||||
container: item.container,
|
||||
createdAt: item.createdAt,
|
||||
deleted: item.deleted,
|
||||
discNumber: item.discNumber,
|
||||
duration: item.duration,
|
||||
genres: relatedGenres(item.genres),
|
||||
imageUrl: image(
|
||||
item.images,
|
||||
options.type,
|
||||
ImageType.PRIMARY,
|
||||
url,
|
||||
item.remoteId
|
||||
),
|
||||
releaseDate: item.releaseDate,
|
||||
releaseYear: item.releaseYear,
|
||||
remoteCreatedAt: item.remoteCreatedAt,
|
||||
remoteId: item.remoteId,
|
||||
// serverFolderId: item.serverFolderId,
|
||||
serverId: item.serverId,
|
||||
streamUrl: stream,
|
||||
trackNumber: item.trackNumber,
|
||||
updatedAt: item.updatedAt,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
type DbAlbum = Album & DbAlbumInclude;
|
||||
|
||||
type DbAlbumInclude = {
|
||||
_count: {
|
||||
favorites: number;
|
||||
songs: number;
|
||||
};
|
||||
albumArtists: AlbumArtist[];
|
||||
genres: Genre[];
|
||||
images: Image[];
|
||||
ratings: AlbumRating[];
|
||||
server: Server;
|
||||
serverFolders: ServerFolder[];
|
||||
songs?: DbSong[];
|
||||
};
|
||||
|
||||
const albums = (options: {
|
||||
items: DbAlbum[] | any[];
|
||||
serverUrl?: string;
|
||||
user: User;
|
||||
}) => {
|
||||
const { items, serverUrl, user } = options;
|
||||
return (
|
||||
items?.map((item) => {
|
||||
const { type, token, remoteUserId } = item.server;
|
||||
const url = serverUrl || item.server.url;
|
||||
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
sortName: item.sortName,
|
||||
releaseDate: item.releaseDate,
|
||||
releaseYear: item.releaseYear,
|
||||
isFavorite: item.favorites.length === 1,
|
||||
rating: rating(item.ratings),
|
||||
songCount: item._count.songs,
|
||||
type,
|
||||
imageUrl: image(
|
||||
item.images,
|
||||
type,
|
||||
ImageType.PRIMARY,
|
||||
url,
|
||||
item.remoteId
|
||||
),
|
||||
backdropImageUrl: image(
|
||||
item.images,
|
||||
type,
|
||||
ImageType.BACKDROP,
|
||||
url,
|
||||
item.remoteId
|
||||
),
|
||||
deleted: item.deleted,
|
||||
remoteId: item.remoteId,
|
||||
remoteCreatedAt: item.remoteCreatedAt,
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
genres: item.genres ? relatedGenres(item.genres) : [],
|
||||
albumArtists: item.albumArtists
|
||||
? relatedAlbumArtists(item.albumArtists)
|
||||
: [],
|
||||
artists: item.artists ? relatedArtists(item.artists) : [],
|
||||
serverFolders: relatedServerFolders(item.serverFolders),
|
||||
songs:
|
||||
item.songs &&
|
||||
songs(item.songs, {
|
||||
deviceId: user.deviceId,
|
||||
token,
|
||||
type,
|
||||
url,
|
||||
userId: remoteUserId,
|
||||
}),
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
// const relatedServerCredentials = (items: ServerCredential[]) => {
|
||||
// return (
|
||||
// items.map((item) => {
|
||||
// return {
|
||||
// /* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
// id: item.id,
|
||||
// enabled: item.enabled,
|
||||
// username: item.username,
|
||||
// credential: item.credential,
|
||||
// /* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
// };
|
||||
// }) || []
|
||||
// );
|
||||
// };
|
||||
|
||||
// const serverCredentials = (items: ServerCredential[]) => {
|
||||
// return (
|
||||
// items.map((item) => {
|
||||
// return {
|
||||
// /* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
// id: item.id,
|
||||
// username: item.username,
|
||||
// enabled: item.enabled,
|
||||
// credential: item.credential,
|
||||
// createdAt: item.createdAt,
|
||||
// updatedAt: item.updatedAt,
|
||||
// /* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
// };
|
||||
// }) || []
|
||||
// );
|
||||
// };
|
||||
|
||||
const servers = (
|
||||
items: (Server & {
|
||||
serverFolders?: ServerFolder[];
|
||||
serverUrls?: (ServerUrl & {
|
||||
userServerUrls?: UserServerUrl[];
|
||||
})[];
|
||||
})[]
|
||||
) => {
|
||||
return (
|
||||
items.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
url: item.url,
|
||||
type: item.type,
|
||||
username: item.username,
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
serverFolders:
|
||||
item.serverFolders && relatedServerFolders(item.serverFolders),
|
||||
serverUrls: item.serverUrls && relatedServerUrls(item.serverUrls),
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
const relatedServerFolderPermissions = (items: ServerFolderPermission[]) => {
|
||||
return items.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
serverFolderId: item.serverFolderId,
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const relatedServerPermissions = (items: ServerPermission[]) => {
|
||||
return items.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
type: item.type,
|
||||
serverId: item.serverId,
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const users = (
|
||||
items: (User & {
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
serverFolderPermissions?: ServerFolderPermission[];
|
||||
serverPermissions?: ServerPermission[];
|
||||
})[]
|
||||
) => {
|
||||
return (
|
||||
items.map((item) => {
|
||||
return {
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
id: item.id,
|
||||
username: item.username,
|
||||
accessToken: item.accessToken,
|
||||
refreshToken: item.refreshToken,
|
||||
enabled: item.enabled,
|
||||
isAdmin: item.isAdmin,
|
||||
deviceId: item.deviceId,
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
flatServerPermissions:
|
||||
item.serverPermissions && item.serverPermissions.map((s) => s.id),
|
||||
serverFolderPermissions:
|
||||
item.serverFolderPermissions &&
|
||||
relatedServerFolderPermissions(item.serverFolderPermissions),
|
||||
serverPermissions:
|
||||
item.serverPermissions &&
|
||||
relatedServerPermissions(item.serverPermissions),
|
||||
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
export const toApiModel = {
|
||||
albums,
|
||||
servers,
|
||||
songs,
|
||||
users,
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import { albumHelpers } from './albums.helpers';
|
||||
import { sharedHelpers } from './shared.helpers';
|
||||
import { songHelpers } from './songs.helpers';
|
||||
|
||||
export const helpers = {
|
||||
albums: albumHelpers,
|
||||
shared: sharedHelpers,
|
||||
songs: songHelpers,
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
import { AuthUser } from '@/middleware';
|
||||
import { ApiError } from '@/utils';
|
||||
import { prisma } from '@lib/prisma';
|
||||
|
||||
const checkServerPermissions = (
|
||||
user: AuthUser,
|
||||
options: { serverId?: string }
|
||||
) => {
|
||||
const { serverId } = options;
|
||||
|
||||
if (user.isAdmin || !serverId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverId && !user.flatServerPermissions.includes(serverId)) {
|
||||
throw ApiError.forbidden();
|
||||
}
|
||||
};
|
||||
|
||||
const checkServerFolderPermissions = (
|
||||
user: AuthUser,
|
||||
options: { serverFolderId?: string[] | string }
|
||||
) => {
|
||||
const { serverFolderId } = options;
|
||||
|
||||
if (user.isAdmin || !serverFolderId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ids: string[] = [];
|
||||
if (typeof serverFolderId === 'string') {
|
||||
ids = [serverFolderId];
|
||||
} else if (typeof serverFolderId === 'object') {
|
||||
ids = serverFolderId;
|
||||
}
|
||||
|
||||
for (const id of ids) {
|
||||
if (!user.flatServerFolderPermissions.includes(id)) {
|
||||
throw ApiError.forbidden('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getAvailableServerFolderIds = async (
|
||||
user: AuthUser,
|
||||
options: { serverId: string }
|
||||
) => {
|
||||
const { serverId } = options;
|
||||
|
||||
if (user.isAdmin) {
|
||||
const serverFoldersWithAccess = await prisma.serverFolder.findMany({
|
||||
where: { serverId },
|
||||
});
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
const serverFolderFilter = (serverFolderIds: string[]) => {
|
||||
return {
|
||||
serverFolders: { every: { id: { in: serverFolderIds } } },
|
||||
};
|
||||
};
|
||||
|
||||
const paginationParams = (options: { skip: any; take: any }) => {
|
||||
const { skip, take } = options;
|
||||
|
||||
return {
|
||||
skip: Number(skip),
|
||||
take: Number(take),
|
||||
};
|
||||
};
|
||||
|
||||
export const sharedHelpers = {
|
||||
checkServerFolderPermissions,
|
||||
checkServerPermissions,
|
||||
getAvailableServerFolderIds,
|
||||
params: {
|
||||
pagination: paginationParams,
|
||||
},
|
||||
serverFolderFilter,
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
const include = () => {
|
||||
const props: Prisma.SongInclude = {
|
||||
album: true,
|
||||
artists: true,
|
||||
externals: true,
|
||||
genres: true,
|
||||
images: true,
|
||||
ratings: true,
|
||||
server: {
|
||||
include: { serverUrls: true },
|
||||
},
|
||||
};
|
||||
|
||||
return props;
|
||||
};
|
||||
|
||||
const findMany = () => {
|
||||
const props: Prisma.SongFindManyArgs = {
|
||||
include: {
|
||||
album: true,
|
||||
artists: true,
|
||||
externals: true,
|
||||
genres: true,
|
||||
images: true,
|
||||
ratings: true,
|
||||
server: {
|
||||
include: { serverUrls: true },
|
||||
},
|
||||
},
|
||||
orderBy: [
|
||||
// { albumId: Prisma.SortOrder.asc },
|
||||
{ discNumber: Prisma.SortOrder.asc },
|
||||
{ trackNumber: Prisma.SortOrder.asc },
|
||||
],
|
||||
};
|
||||
|
||||
return props;
|
||||
};
|
||||
|
||||
export const songHelpers = {
|
||||
findMany,
|
||||
include,
|
||||
};
|
||||
Reference in New Issue
Block a user