Add populate script and artist api

This commit is contained in:
Zoe Roux
2022-10-25 02:15:19 +09:00
committed by Bluub
parent 72be838324
commit 89dbee0b17
22 changed files with 461 additions and 104 deletions
+4 -2
View File
@@ -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 {}
+18
View File
@@ -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();
});
});
+70
View File
@@ -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;
}
}
+18
View File
@@ -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();
});
});
+43
View File
@@ -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,
});
}
}
+8
View File
@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';
export class CreateArtistDto {
@IsNotEmpty()
@ApiProperty()
name: string;
}
+2
View File
@@ -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();
+17
View File
@@ -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;
}
+40 -2
View File
@@ -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;