Add populate script and artist api
This commit is contained in:
@@ -7,10 +7,12 @@ import { PrismaModule } from './prisma/prisma.module';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { SongModule } from './song/song.module';
|
||||
import { LessonModule } from './lesson/lesson.module';
|
||||
import { ArtistController } from './artist/artist.controller';
|
||||
import { ArtistService } from './artist/artist.service';
|
||||
|
||||
@Module({
|
||||
imports: [UsersModule, PrismaModule, AuthModule, SongModule, LessonModule],
|
||||
controllers: [AppController],
|
||||
providers: [AppService, PrismaService],
|
||||
controllers: [AppController, ArtistController],
|
||||
providers: [AppService, PrismaService, ArtistService],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ArtistController } from './artist.controller';
|
||||
|
||||
describe('ArtistController', () => {
|
||||
let controller: ArtistController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [ArtistController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<ArtistController>(ArtistController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Body,
|
||||
ConflictException,
|
||||
Controller,
|
||||
DefaultValuePipe,
|
||||
Delete,
|
||||
Get,
|
||||
NotFoundException,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import { Plage } from 'src/models/plage';
|
||||
import { CreateArtistDto } from './dto/create-artist.dto';
|
||||
import { Request } from 'express';
|
||||
import { ArtistService } from './artist.service';
|
||||
import { Prisma, Artist } from '@prisma/client';
|
||||
|
||||
@Controller('artist')
|
||||
export class ArtistController {
|
||||
constructor(private readonly service: ArtistService) {}
|
||||
|
||||
@Post()
|
||||
async create(@Body() dto: CreateArtistDto) {
|
||||
try {
|
||||
return await this.service.create(dto);
|
||||
} catch {
|
||||
throw new ConflictException(await this.service.get({ name: dto.name }));
|
||||
}
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
async remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return await this.service.delete({ id });
|
||||
}
|
||||
|
||||
@Get()
|
||||
async findAll(
|
||||
@Req() req: Request,
|
||||
@Query() filter: Prisma.SongWhereInput,
|
||||
@Query('skip', new DefaultValuePipe(0), ParseIntPipe) skip: number,
|
||||
@Query('take', new DefaultValuePipe(20), ParseIntPipe) take: number,
|
||||
): Promise<Plage<Artist>> {
|
||||
try {
|
||||
const ret = await this.service.list({
|
||||
skip,
|
||||
take,
|
||||
where: {
|
||||
...filter,
|
||||
id: filter.id ? +filter.id : undefined,
|
||||
},
|
||||
});
|
||||
return new Plage(ret, req);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw new BadRequestException(null, e?.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
const res = await this.service.get({ id });
|
||||
|
||||
if (res === null) throw new NotFoundException('Artist not found');
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ArtistService } from './artist.service';
|
||||
|
||||
describe('ArtistService', () => {
|
||||
let service: ArtistService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [ArtistService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ArtistService>(ArtistService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Prisma, Artist } from '@prisma/client';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class ArtistService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async create(data: Prisma.ArtistCreateInput): Promise<Artist> {
|
||||
return this.prisma.artist.create({
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async get(where: Prisma.ArtistWhereUniqueInput): Promise<Artist | null> {
|
||||
return this.prisma.artist.findUnique({
|
||||
where,
|
||||
});
|
||||
}
|
||||
|
||||
async list(params: {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
cursor?: Prisma.ArtistWhereUniqueInput;
|
||||
where?: Prisma.ArtistWhereInput;
|
||||
orderBy?: Prisma.ArtistOrderByWithRelationInput;
|
||||
}): Promise<Artist[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params;
|
||||
return this.prisma.artist.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
});
|
||||
}
|
||||
|
||||
async delete(where: Prisma.ArtistWhereUniqueInput): Promise<Artist> {
|
||||
return this.prisma.artist.delete({
|
||||
where,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class CreateArtistDto {
|
||||
@IsNotEmpty()
|
||||
@ApiProperty()
|
||||
name: string;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import { PrismaService } from './prisma/prisma.service';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
@@ -16,6 +17,7 @@ async function bootstrap() {
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
SwaggerModule.setup('api', app, document);
|
||||
|
||||
app.useGlobalPipes(new ValidationPipe());
|
||||
await app.listen(3000);
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
@@ -9,4 +9,21 @@ export class CreateSongDto {
|
||||
@IsNotEmpty()
|
||||
@ApiProperty()
|
||||
difficulties: object;
|
||||
|
||||
@IsNotEmpty()
|
||||
@ApiProperty()
|
||||
midiPath: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@ApiProperty()
|
||||
musicXmlPath: string;
|
||||
|
||||
@ApiProperty()
|
||||
artist?: number;
|
||||
|
||||
@ApiProperty()
|
||||
album?: number;
|
||||
|
||||
@ApiProperty()
|
||||
genre?: number;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Body,
|
||||
ConflictException,
|
||||
Controller,
|
||||
DefaultValuePipe,
|
||||
Delete,
|
||||
@@ -11,20 +12,57 @@ import {
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
StreamableFile,
|
||||
} from '@nestjs/common';
|
||||
import { Plage } from 'src/models/plage';
|
||||
import { CreateSongDto } from './dto/create-song.dto';
|
||||
import { SongService } from './song.service';
|
||||
import { Request } from 'express';
|
||||
import { Prisma, Song } from '@prisma/client';
|
||||
import { createReadStream } from 'fs';
|
||||
|
||||
@Controller('song')
|
||||
export class SongController {
|
||||
constructor(private readonly songService: SongService) {}
|
||||
|
||||
@Get(':id/midi')
|
||||
async getMidi(@Param('id', ParseIntPipe) id: number) {
|
||||
const song = await this.songService.song({ id });
|
||||
if (!song) throw new NotFoundException('Song not found');
|
||||
|
||||
const file = createReadStream(song.midiPath);
|
||||
return new StreamableFile(file);
|
||||
}
|
||||
|
||||
@Get(':id/musicXml')
|
||||
async getMusicXml(@Param('id', ParseIntPipe) id: number) {
|
||||
const song = await this.songService.song({ id });
|
||||
if (!song) throw new NotFoundException('Song not found');
|
||||
|
||||
const file = createReadStream(song.midiPath);
|
||||
return new StreamableFile(file);
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() createSongDto: CreateSongDto) {
|
||||
return await this.songService.createSong(createSongDto);
|
||||
try {
|
||||
return await this.songService.createSong({
|
||||
...createSongDto,
|
||||
artist: createSongDto.artist
|
||||
? { connect: { id: createSongDto.artist } }
|
||||
: undefined,
|
||||
album: createSongDto.album
|
||||
? { connect: { id: createSongDto.album } }
|
||||
: undefined,
|
||||
genre: createSongDto.genre
|
||||
? { connect: { id: createSongDto.genre } }
|
||||
: undefined,
|
||||
});
|
||||
} catch {
|
||||
throw new ConflictException(
|
||||
await this.songService.song({ name: createSongDto.name }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@@ -57,7 +95,7 @@ export class SongController {
|
||||
|
||||
@Get(':id')
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
let res = await this.songService.song({ id });
|
||||
const res = await this.songService.song({ id });
|
||||
|
||||
if (res === null) throw new NotFoundException('Song not found');
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user