mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
feat(api): add getListens endpoint with pagination
This commit is contained in:
parent
a770b48441
commit
de6d057f80
7 changed files with 83 additions and 1 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
|
@ -7709,6 +7709,11 @@
|
||||||
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
|
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nestjs-typeorm-paginate": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/nestjs-typeorm-paginate/-/nestjs-typeorm-paginate-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-cGIVwdIrZuDO5kHSVTcYRyFAjyxbg2dn/YFp9l+/xhsQl9XZkvcfXtqoo32T/h5bUmztdS4GJMoUYwo7TF30Eg=="
|
||||||
|
},
|
||||||
"next-tick": {
|
"next-tick": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
"@nestjs/typeorm": "^7.0.0",
|
"@nestjs/typeorm": "^7.0.0",
|
||||||
"class-transformer": "^0.2.3",
|
"class-transformer": "^0.2.3",
|
||||||
"class-validator": "^0.12.2",
|
"class-validator": "^0.12.2",
|
||||||
|
"nestjs-typeorm-paginate": "^2.0.3",
|
||||||
"passport": "^0.4.1",
|
"passport": "^0.4.1",
|
||||||
"passport-jwt": "^4.0.0",
|
"passport-jwt": "^4.0.0",
|
||||||
"passport-spotify": "^1.1.0",
|
"passport-spotify": "^1.1.0",
|
||||||
|
|
|
||||||
5
src/listens/dto/get-listens.dto.ts
Normal file
5
src/listens/dto/get-listens.dto.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { User } from "src/users/user.entity";
|
||||||
|
|
||||||
|
export interface GetListensDto {
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
18
src/listens/listens.controller.spec.ts
Normal file
18
src/listens/listens.controller.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { Test, TestingModule } from "@nestjs/testing";
|
||||||
|
import { ListensController } from "./listens.controller";
|
||||||
|
|
||||||
|
describe("Listens Controller", () => {
|
||||||
|
let controller: ListensController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [ListensController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<ListensController>(ListensController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be defined", () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
src/listens/listens.controller.ts
Normal file
24
src/listens/listens.controller.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Controller, Get, Query } from "@nestjs/common";
|
||||||
|
import { Pagination } from "nestjs-typeorm-paginate";
|
||||||
|
import { Auth } from "../auth/decorators/auth.decorator";
|
||||||
|
import { ReqUser } from "../auth/decorators/req-user.decorator";
|
||||||
|
import { User } from "../users/user.entity";
|
||||||
|
import { Listen } from "./listen.entity";
|
||||||
|
import { ListensService } from "./listens.service";
|
||||||
|
|
||||||
|
@Controller("api/v1/listens")
|
||||||
|
export class ListensController {
|
||||||
|
constructor(private readonly listensService: ListensService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@Auth()
|
||||||
|
async getRecentlyPlayed(
|
||||||
|
@Query("page") page: number = 1,
|
||||||
|
@Query("limit") limit: number = 10,
|
||||||
|
@ReqUser() user: User
|
||||||
|
): Promise<Pagination<Listen>> {
|
||||||
|
limit = limit > 100 ? 100 : limit;
|
||||||
|
|
||||||
|
return this.listensService.getListens({ page, limit, user });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,12 @@ import { Module } from "@nestjs/common";
|
||||||
import { ListensService } from "./listens.service";
|
import { ListensService } from "./listens.service";
|
||||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||||
import { ListenRepository } from "./listen.repository";
|
import { ListenRepository } from "./listen.repository";
|
||||||
|
import { ListensController } from "./listens.controller";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([ListenRepository])],
|
imports: [TypeOrmModule.forFeature([ListenRepository])],
|
||||||
providers: [ListensService],
|
providers: [ListensService],
|
||||||
exports: [ListensService],
|
exports: [ListensService],
|
||||||
|
controllers: [ListensController],
|
||||||
})
|
})
|
||||||
export class ListensModule {}
|
export class ListensModule {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
import { Injectable } from "@nestjs/common";
|
import { Injectable } from "@nestjs/common";
|
||||||
|
import {
|
||||||
|
IPaginationOptions,
|
||||||
|
paginate,
|
||||||
|
Pagination,
|
||||||
|
} from "nestjs-typeorm-paginate";
|
||||||
|
import { CreateListenDto } from "./dto/create-listen.dto";
|
||||||
import { Listen } from "./listen.entity";
|
import { Listen } from "./listen.entity";
|
||||||
import { ListenRepository } from "./listen.repository";
|
import { ListenRepository } from "./listen.repository";
|
||||||
import { CreateListenDto } from "./dto/create-listen.dto";
|
import { GetListensDto } from "./dto/get-listens.dto";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ListensService {
|
export class ListensService {
|
||||||
|
|
@ -32,4 +38,25 @@ export class ListensService {
|
||||||
|
|
||||||
return listen;
|
return listen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getListens(
|
||||||
|
options: GetListensDto & IPaginationOptions
|
||||||
|
): Promise<Pagination<Listen>> {
|
||||||
|
const { page, limit, user } = options;
|
||||||
|
|
||||||
|
const queryBuilder = this.listenRepository
|
||||||
|
.createQueryBuilder("l")
|
||||||
|
.leftJoin("l.user", "user")
|
||||||
|
.where("user.id = :userID", { userID: user.id })
|
||||||
|
.leftJoinAndSelect("l.track", "track")
|
||||||
|
.leftJoinAndSelect("track.artists", "artists")
|
||||||
|
.leftJoinAndSelect("track.album", "album")
|
||||||
|
.leftJoinAndSelect("album.artists", "albumArtists")
|
||||||
|
.orderBy("l.playedAt", "DESC");
|
||||||
|
|
||||||
|
return paginate<Listen>(queryBuilder, {
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue