Add includable fields for all ressources
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOkResponsePlaginated, Plage } from 'src/models/plage';
|
||||
import { CreateAlbumDto } from './dto/create-album.dto';
|
||||
@@ -21,11 +22,18 @@ import { Prisma, Album } from '@prisma/client';
|
||||
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { FilterQuery } from 'src/utils/filter.pipe';
|
||||
import { Album as _Album } from 'src/_gen/prisma-class/album';
|
||||
import { IncludeMap, mapInclude } from 'src/utils/include';
|
||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
||||
|
||||
@Controller('album')
|
||||
@ApiTags('album')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class AlbumController {
|
||||
static filterableFields: string[] = ['+id', 'name', '+artistId'];
|
||||
static includableFields: IncludeMap<Prisma.AlbumInclude> = {
|
||||
artist: true,
|
||||
Song: true,
|
||||
};
|
||||
|
||||
constructor(private readonly albumService: AlbumService) {}
|
||||
|
||||
@@ -65,6 +73,7 @@ export class AlbumController {
|
||||
@Req() req: Request,
|
||||
@FilterQuery(AlbumController.filterableFields)
|
||||
where: Prisma.AlbumWhereInput,
|
||||
@Query('include') include: string,
|
||||
@Query('skip', new DefaultValuePipe(0), ParseIntPipe) skip: number,
|
||||
@Query('take', new DefaultValuePipe(20), ParseIntPipe) take: number,
|
||||
): Promise<Plage<Album>> {
|
||||
@@ -72,6 +81,7 @@ export class AlbumController {
|
||||
skip,
|
||||
take,
|
||||
where,
|
||||
include: mapInclude(include, req, AlbumController.includableFields),
|
||||
});
|
||||
return new Plage(ret, req);
|
||||
}
|
||||
@@ -79,8 +89,15 @@ export class AlbumController {
|
||||
@Get(':id')
|
||||
@ApiOperation({ description: 'Get an album by id' })
|
||||
@ApiOkResponse({ type: _Album })
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
const res = await this.albumService.album({ id });
|
||||
async findOne(
|
||||
@Req() req: Request,
|
||||
@Query('include') include: string,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
) {
|
||||
const res = await this.albumService.album(
|
||||
{ id },
|
||||
mapInclude(include, req, AlbumController.includableFields),
|
||||
);
|
||||
|
||||
if (res === null) throw new NotFoundException('Album not found');
|
||||
return res;
|
||||
|
||||
@@ -14,9 +14,11 @@ export class AlbumService {
|
||||
|
||||
async album(
|
||||
albumWhereUniqueInput: Prisma.AlbumWhereUniqueInput,
|
||||
include?: Prisma.AlbumInclude,
|
||||
): Promise<Album | null> {
|
||||
return this.prisma.album.findUnique({
|
||||
where: albumWhereUniqueInput,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,14 +28,16 @@ export class AlbumService {
|
||||
cursor?: Prisma.AlbumWhereUniqueInput;
|
||||
where?: Prisma.AlbumWhereInput;
|
||||
orderBy?: Prisma.AlbumOrderByWithRelationInput;
|
||||
include?: Prisma.AlbumInclude;
|
||||
}): Promise<Album[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params;
|
||||
const { skip, take, cursor, where, orderBy, include } = params;
|
||||
return this.prisma.album.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Query,
|
||||
Req,
|
||||
StreamableFile,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOkResponsePlaginated, Plage } from 'src/models/plage';
|
||||
import { CreateArtistDto } from './dto/create-artist.dto';
|
||||
@@ -29,11 +30,18 @@ import {
|
||||
import { createReadStream, existsSync } from 'fs';
|
||||
import { FilterQuery } from 'src/utils/filter.pipe';
|
||||
import { Artist as _Artist } from 'src/_gen/prisma-class/artist';
|
||||
import { IncludeMap, mapInclude } from 'src/utils/include';
|
||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
||||
|
||||
@Controller('artist')
|
||||
@ApiTags('artist')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class ArtistController {
|
||||
static filterableFields = ['+id', 'name'];
|
||||
static includableFields: IncludeMap<Prisma.ArtistInclude> = {
|
||||
Song: true,
|
||||
Album: true,
|
||||
};
|
||||
|
||||
constructor(private readonly service: ArtistService) {}
|
||||
|
||||
@@ -84,6 +92,7 @@ export class ArtistController {
|
||||
@Req() req: Request,
|
||||
@FilterQuery(ArtistController.filterableFields)
|
||||
where: Prisma.ArtistWhereInput,
|
||||
@Query('include') include: string,
|
||||
@Query('skip', new DefaultValuePipe(0), ParseIntPipe) skip: number,
|
||||
@Query('take', new DefaultValuePipe(20), ParseIntPipe) take: number,
|
||||
): Promise<Plage<Artist>> {
|
||||
@@ -91,6 +100,7 @@ export class ArtistController {
|
||||
skip,
|
||||
take,
|
||||
where,
|
||||
include: mapInclude(include, req, ArtistController.includableFields),
|
||||
});
|
||||
return new Plage(ret, req);
|
||||
}
|
||||
@@ -98,8 +108,15 @@ export class ArtistController {
|
||||
@Get(':id')
|
||||
@ApiOperation({ description: 'Get an artist by id' })
|
||||
@ApiOkResponse({ type: _Artist })
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
const res = await this.service.get({ id });
|
||||
async findOne(
|
||||
@Req() req: Request,
|
||||
@Query('include') include: string,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
) {
|
||||
const res = await this.service.get(
|
||||
{ id },
|
||||
mapInclude(include, req, ArtistController.includableFields),
|
||||
);
|
||||
|
||||
if (res === null) throw new NotFoundException('Artist not found');
|
||||
return res;
|
||||
|
||||
@@ -12,9 +12,13 @@ export class ArtistService {
|
||||
});
|
||||
}
|
||||
|
||||
async get(where: Prisma.ArtistWhereUniqueInput): Promise<Artist | null> {
|
||||
async get(
|
||||
where: Prisma.ArtistWhereUniqueInput,
|
||||
include?: Prisma.ArtistInclude,
|
||||
): Promise<Artist | null> {
|
||||
return this.prisma.artist.findUnique({
|
||||
where,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,14 +28,16 @@ export class ArtistService {
|
||||
cursor?: Prisma.ArtistWhereUniqueInput;
|
||||
where?: Prisma.ArtistWhereInput;
|
||||
orderBy?: Prisma.ArtistOrderByWithRelationInput;
|
||||
include?: Prisma.ArtistInclude;
|
||||
}): Promise<Artist[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params;
|
||||
const { skip, take, cursor, where, orderBy, include } = params;
|
||||
return this.prisma.artist.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Query,
|
||||
Req,
|
||||
StreamableFile,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOkResponsePlaginated, Plage } from 'src/models/plage';
|
||||
import { CreateGenreDto } from './dto/create-genre.dto';
|
||||
@@ -23,11 +24,17 @@ import { ApiTags } from '@nestjs/swagger';
|
||||
import { createReadStream, existsSync } from 'fs';
|
||||
import { FilterQuery } from 'src/utils/filter.pipe';
|
||||
import { Genre as _Genre } from 'src/_gen/prisma-class/genre';
|
||||
import { IncludeMap, mapInclude } from 'src/utils/include';
|
||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
||||
|
||||
@Controller('genre')
|
||||
@ApiTags('genre')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class GenreController {
|
||||
static filterableFields: string[] = ['+id', 'name'];
|
||||
static includableFields: IncludeMap<Prisma.GenreInclude> = {
|
||||
Song: true,
|
||||
};
|
||||
|
||||
constructor(private readonly service: GenreService) {}
|
||||
|
||||
@@ -71,6 +78,7 @@ export class GenreController {
|
||||
@Req() req: Request,
|
||||
@FilterQuery(GenreController.filterableFields)
|
||||
where: Prisma.GenreWhereInput,
|
||||
@Query('include') include: string,
|
||||
@Query('skip', new DefaultValuePipe(0), ParseIntPipe) skip: number,
|
||||
@Query('take', new DefaultValuePipe(20), ParseIntPipe) take: number,
|
||||
): Promise<Plage<Genre>> {
|
||||
@@ -78,13 +86,21 @@ export class GenreController {
|
||||
skip,
|
||||
take,
|
||||
where,
|
||||
include: mapInclude(include, req, GenreController.includableFields),
|
||||
});
|
||||
return new Plage(ret, req);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
const res = await this.service.get({ id });
|
||||
async findOne(
|
||||
@Req() req: Request,
|
||||
@Query('include') include: string,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
) {
|
||||
const res = await this.service.get(
|
||||
{ id },
|
||||
mapInclude(include, req, GenreController.includableFields),
|
||||
);
|
||||
|
||||
if (res === null) throw new NotFoundException('Genre not found');
|
||||
return res;
|
||||
|
||||
@@ -12,9 +12,13 @@ export class GenreService {
|
||||
});
|
||||
}
|
||||
|
||||
async get(where: Prisma.GenreWhereUniqueInput): Promise<Genre | null> {
|
||||
async get(
|
||||
where: Prisma.GenreWhereUniqueInput,
|
||||
include?: Prisma.GenreInclude,
|
||||
): Promise<Genre | null> {
|
||||
return this.prisma.genre.findUnique({
|
||||
where,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,14 +28,16 @@ export class GenreService {
|
||||
cursor?: Prisma.GenreWhereUniqueInput;
|
||||
where?: Prisma.GenreWhereInput;
|
||||
orderBy?: Prisma.GenreOrderByWithRelationInput;
|
||||
include?: Prisma.GenreInclude;
|
||||
}): Promise<Genre[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params;
|
||||
const { skip, take, cursor, where, orderBy, include } = params;
|
||||
return this.prisma.genre.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
Get,
|
||||
Query,
|
||||
Req,
|
||||
Request,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
DefaultValuePipe,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
Body,
|
||||
Delete,
|
||||
NotFoundException,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOkResponsePlaginated, Plage } from 'src/models/plage';
|
||||
import { LessonService } from './lesson.service';
|
||||
@@ -19,6 +19,9 @@ import { ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';
|
||||
import { Prisma, Skill } from '@prisma/client';
|
||||
import { FilterQuery } from 'src/utils/filter.pipe';
|
||||
import { Lesson as _Lesson } from 'src/_gen/prisma-class/lesson';
|
||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
||||
import { IncludeMap, mapInclude } from 'src/utils/include';
|
||||
import { Request } from 'express';
|
||||
|
||||
export class Lesson {
|
||||
@ApiProperty()
|
||||
@@ -35,6 +38,7 @@ export class Lesson {
|
||||
|
||||
@ApiTags('lessons')
|
||||
@Controller('lesson')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class LessonController {
|
||||
static filterableFields: string[] = [
|
||||
'+id',
|
||||
@@ -42,6 +46,9 @@ export class LessonController {
|
||||
'+requiredLevel',
|
||||
'mainSkill',
|
||||
];
|
||||
static includableFields: IncludeMap<Prisma.LessonInclude> = {
|
||||
LessonHistory: true,
|
||||
};
|
||||
|
||||
constructor(private lessonService: LessonService) {}
|
||||
|
||||
@@ -54,6 +61,7 @@ export class LessonController {
|
||||
@Req() request: Request,
|
||||
@FilterQuery(LessonController.filterableFields)
|
||||
where: Prisma.LessonWhereInput,
|
||||
@Query('include') include: string,
|
||||
@Query('skip', new DefaultValuePipe(0), ParseIntPipe) skip: number,
|
||||
@Query('take', new DefaultValuePipe(20), ParseIntPipe) take: number,
|
||||
): Promise<Plage<Lesson>> {
|
||||
@@ -61,6 +69,7 @@ export class LessonController {
|
||||
skip,
|
||||
take,
|
||||
where,
|
||||
include: mapInclude(include, request, LessonController.includableFields),
|
||||
});
|
||||
return new Plage(ret, request);
|
||||
}
|
||||
@@ -69,8 +78,15 @@ export class LessonController {
|
||||
summary: 'Get a particular lessons',
|
||||
})
|
||||
@Get(':id')
|
||||
async get(@Param('id', ParseIntPipe) id: number): Promise<Lesson> {
|
||||
const ret = await this.lessonService.get(id);
|
||||
async get(
|
||||
@Req() req: Request,
|
||||
@Query('include') include: string,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
): Promise<Lesson> {
|
||||
const ret = await this.lessonService.get(
|
||||
id,
|
||||
mapInclude(include, req, LessonController.includableFields),
|
||||
);
|
||||
if (!ret) throw new NotFoundException();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -12,22 +12,28 @@ export class LessonService {
|
||||
cursor?: Prisma.LessonWhereUniqueInput;
|
||||
where?: Prisma.LessonWhereInput;
|
||||
orderBy?: Prisma.LessonOrderByWithRelationInput;
|
||||
include?: Prisma.LessonInclude;
|
||||
}): Promise<Lesson[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params;
|
||||
const { skip, take, cursor, where, orderBy, include } = params;
|
||||
return this.prisma.lesson.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
async get(id: number): Promise<Lesson | null> {
|
||||
async get(
|
||||
id: number,
|
||||
include?: Prisma.LessonInclude,
|
||||
): Promise<Lesson | null> {
|
||||
return this.prisma.lesson.findFirst({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Post,
|
||||
Query,
|
||||
Request,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
@@ -26,6 +27,10 @@ import { SearchService } from './search.service';
|
||||
import { Song as _Song } from 'src/_gen/prisma-class/song';
|
||||
import { Genre as _Genre } from 'src/_gen/prisma-class/genre';
|
||||
import { Artist as _Artist } from 'src/_gen/prisma-class/artist';
|
||||
import { mapInclude } from 'src/utils/include';
|
||||
import { SongController } from 'src/song/song.controller';
|
||||
import { GenreController } from 'src/genre/genre.controller';
|
||||
import { ArtistController } from 'src/artist/artist.controller';
|
||||
|
||||
@ApiTags('search')
|
||||
@Controller('search')
|
||||
@@ -39,10 +44,15 @@ export class SearchController {
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async searchSong(
|
||||
@Request() req: any,
|
||||
@Query('include') include: string,
|
||||
@Param('query') query: string,
|
||||
): Promise<Song[] | null> {
|
||||
try {
|
||||
const ret = await this.searchService.songByGuess(query, req.user?.id);
|
||||
const ret = await this.searchService.songByGuess(
|
||||
query,
|
||||
req.user?.id,
|
||||
mapInclude(include, req, SongController.includableFields),
|
||||
);
|
||||
if (!ret.length) throw new NotFoundException();
|
||||
else return ret;
|
||||
} catch (error) {
|
||||
@@ -57,10 +67,15 @@ export class SearchController {
|
||||
@ApiOperation({ description: 'Search a genre' })
|
||||
async searchGenre(
|
||||
@Request() req: any,
|
||||
@Query('include') include: string,
|
||||
@Param('query') query: string,
|
||||
): Promise<Genre[] | null> {
|
||||
try {
|
||||
const ret = await this.searchService.genreByGuess(query, req.user?.id);
|
||||
const ret = await this.searchService.genreByGuess(
|
||||
query,
|
||||
req.user?.id,
|
||||
mapInclude(include, req, GenreController.includableFields),
|
||||
);
|
||||
if (!ret.length) throw new NotFoundException();
|
||||
else return ret;
|
||||
} catch (error) {
|
||||
@@ -75,10 +90,15 @@ export class SearchController {
|
||||
@ApiOperation({ description: 'Search an artist' })
|
||||
async searchArtists(
|
||||
@Request() req: any,
|
||||
@Query('include') include: string,
|
||||
@Param('query') query: string,
|
||||
): Promise<Artist[] | null> {
|
||||
try {
|
||||
const ret = await this.searchService.artistByGuess(query, req.user?.id);
|
||||
const ret = await this.searchService.artistByGuess(
|
||||
query,
|
||||
req.user?.id,
|
||||
mapInclude(include, req, ArtistController.includableFields),
|
||||
);
|
||||
if (!ret.length) throw new NotFoundException();
|
||||
else return ret;
|
||||
} catch (error) {
|
||||
|
||||
@@ -10,27 +10,42 @@ export class SearchService {
|
||||
private history: HistoryService,
|
||||
) {}
|
||||
|
||||
async songByGuess(query: string, userID: number): Promise<Song[]> {
|
||||
async songByGuess(
|
||||
query: string,
|
||||
userID: number,
|
||||
include?: Prisma.SongInclude,
|
||||
): Promise<Song[]> {
|
||||
return this.prisma.song.findMany({
|
||||
where: {
|
||||
name: { contains: query, mode: 'insensitive' },
|
||||
},
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
async genreByGuess(query: string, userID: number): Promise<Genre[]> {
|
||||
async genreByGuess(
|
||||
query: string,
|
||||
userID: number,
|
||||
include?: Prisma.GenreInclude,
|
||||
): Promise<Genre[]> {
|
||||
return this.prisma.genre.findMany({
|
||||
where: {
|
||||
name: { contains: query, mode: 'insensitive' },
|
||||
},
|
||||
include,
|
||||
});
|
||||
}
|
||||
|
||||
async artistByGuess(query: string, userID: number): Promise<Artist[]> {
|
||||
async artistByGuess(
|
||||
query: string,
|
||||
userID: number,
|
||||
include?: Prisma.ArtistInclude,
|
||||
): Promise<Artist[]> {
|
||||
return this.prisma.artist.findMany({
|
||||
where: {
|
||||
name: { contains: query, mode: 'insensitive' },
|
||||
},
|
||||
include,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ class SongHistoryResult {
|
||||
|
||||
@Controller('song')
|
||||
@ApiTags('song')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class SongController {
|
||||
static filterableFields: string[] = [
|
||||
'+id',
|
||||
@@ -54,7 +55,7 @@ export class SongController {
|
||||
'+albumId',
|
||||
'+genreId',
|
||||
];
|
||||
static includableFileds: IncludeMap<Prisma.SongInclude> = {
|
||||
static includableFields: IncludeMap<Prisma.SongInclude> = {
|
||||
artist: true,
|
||||
album: true,
|
||||
genre: true,
|
||||
@@ -168,13 +169,12 @@ export class SongController {
|
||||
skip,
|
||||
take,
|
||||
where,
|
||||
include: mapInclude(include, req, SongController.includableFileds),
|
||||
include: mapInclude(include, req, SongController.includableFields),
|
||||
});
|
||||
return new Plage(ret, req);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiOperation({ description: 'Get a specific song data' })
|
||||
@ApiNotFoundResponse({ description: 'Song not found' })
|
||||
@ApiOkResponse({ type: _Song, description: 'Requested song' })
|
||||
@@ -187,7 +187,7 @@ export class SongController {
|
||||
{
|
||||
id,
|
||||
},
|
||||
mapInclude(include, req, SongController.includableFileds),
|
||||
mapInclude(include, req, SongController.includableFields),
|
||||
);
|
||||
|
||||
if (res === null) throw new NotFoundException('Song not found');
|
||||
@@ -196,7 +196,6 @@ export class SongController {
|
||||
|
||||
@Get(':id/history')
|
||||
@HttpCode(200)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiOperation({
|
||||
description: 'get the history of the connected user on a specific song',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user