chore(api): update dependencies

This commit is contained in:
Julian Tölle 2020-05-02 17:17:20 +02:00
parent 05f230a7ce
commit d881a78757
37 changed files with 4804 additions and 2700 deletions

View file

@ -1,7 +1,7 @@
################## ##################
## common ## common
################## ##################
FROM node:12-alpine as common FROM node:14-alpine as common
LABEL org.label-schema.schema-version="1.0" \ LABEL org.label-schema.schema-version="1.0" \
org.label-schema.name="listory" \ org.label-schema.name="listory" \
stage="common" stage="common"

7218
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
"scripts": { "scripts": {
"prebuild": "rimraf dist", "prebuild": "rimraf dist",
"build": "nest build", "build": "nest build",
"format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\"",
"start": "nest start", "start": "nest start",
"start:dev": "nest start --watch", "start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch", "start:debug": "nest start --debug --watch",
@ -20,47 +20,47 @@
"test:e2e": "jest --config ./apps/listory/test/jest-e2e.json" "test:e2e": "jest --config ./apps/listory/test/jest-e2e.json"
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^6.7.2", "@nestjs/common": "^7.0.9",
"@nestjs/config": "^0.1.0", "@nestjs/config": "^0.4.0",
"@nestjs/core": "^6.7.2", "@nestjs/core": "^7.0.9",
"@nestjs/jwt": "^6.1.1", "@nestjs/jwt": "^7.0.0",
"@nestjs/passport": "^6.1.1", "@nestjs/passport": "^7.0.0",
"@nestjs/platform-express": "^6.7.2", "@nestjs/platform-express": "^7.0.9",
"@nestjs/schedule": "^0.2.0", "@nestjs/schedule": "^0.3.1",
"@nestjs/swagger": "^4.2.3", "@nestjs/swagger": "^4.5.3",
"@nestjs/typeorm": "^6.2.0", "@nestjs/typeorm": "^7.0.0",
"class-transformer": "^0.2.3", "class-transformer": "^0.2.3",
"class-validator": "^0.11.0", "class-validator": "^0.12.2",
"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",
"pg": "^7.17.1", "pg": "^8.0.3",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rimraf": "^3.0.0", "rimraf": "^3.0.2",
"rxjs": "^6.5.3", "rxjs": "^6.5.5",
"swagger-ui-express": "^4.1.3", "swagger-ui-express": "^4.1.4",
"typeorm": "^0.2.22" "typeorm": "^0.2.24"
}, },
"devDependencies": { "devDependencies": {
"@nestjs/cli": "^6.9.0", "@nestjs/cli": "^7.1.4",
"@nestjs/schematics": "^6.7.0", "@nestjs/schematics": "^7.0.0",
"@nestjs/testing": "^6.7.1", "@nestjs/testing": "^7.0.9",
"@types/express": "^4.17.1", "@types/express": "^4.17.6",
"@types/jest": "^24.0.18", "@types/jest": "^25.2.1",
"@types/node": "^12.7.5", "@types/node": "^13.13.4",
"@types/passport-jwt": "^3.0.3", "@types/passport-jwt": "^3.0.3",
"@types/supertest": "^2.0.8", "@types/supertest": "^2.0.9",
"jest": "^24.9.0", "jest": "^25.5.4",
"prettier": "^1.18.2", "prettier": "^2.0.5",
"supertest": "^4.0.2", "supertest": "^4.0.2",
"ts-jest": "^24.1.0", "ts-jest": "^25.4.0",
"ts-loader": "^6.1.1", "ts-loader": "^7.0.2",
"ts-node": "^8.4.1", "ts-node": "^8.9.1",
"tsconfig-paths": "^3.9.0", "tsconfig-paths": "^3.9.0",
"tslint": "^5.20.0", "tslint": "^6.1.2",
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.1.0", "tslint-plugin-prettier": "^2.3.0",
"typescript": "^3.6.3" "typescript": "^3.8.3"
}, },
"jest": { "jest": {
"moduleFileExtensions": [ "moduleFileExtensions": [

View file

@ -17,7 +17,7 @@ import { UsersModule } from "./users/users.module";
UsersModule, UsersModule,
SourcesModule, SourcesModule,
MusicLibraryModule, MusicLibraryModule,
ListensModule ListensModule,
] ],
}) })
export class AppModule {} export class AppModule {}

View file

@ -31,7 +31,7 @@ export class AuthController {
maxAge: 15 * 60 * 1000, maxAge: 15 * 60 * 1000,
// Must be readable by SPA // Must be readable by SPA
httpOnly: false httpOnly: false,
}); });
// Redirect User to SPA // Redirect User to SPA

View file

@ -14,14 +14,14 @@ import { SpotifyStrategy } from "./spotify.strategy";
JwtModule.registerAsync({ JwtModule.registerAsync({
useFactory: (config: ConfigService) => ({ useFactory: (config: ConfigService) => ({
secret: config.get<string>("JWT_SECRET"), secret: config.get<string>("JWT_SECRET"),
signOptions: { expiresIn: config.get<string>("JWT_EXPIRATION_TIME") } signOptions: { expiresIn: config.get<string>("JWT_EXPIRATION_TIME") },
}), }),
inject: [ConfigService] inject: [ConfigService],
}), }),
UsersModule UsersModule,
], ],
providers: [AuthService, SpotifyStrategy, JwtStrategy], providers: [AuthService, SpotifyStrategy, JwtStrategy],
exports: [PassportModule], exports: [PassportModule],
controllers: [AuthController] controllers: [AuthController],
}) })
export class AuthModule {} export class AuthModule {}

View file

@ -6,7 +6,7 @@ describe("AuthService", () => {
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [AuthService] providers: [AuthService],
}).compile(); }).compile();
service = module.get<AuthService>(AuthService); service = module.get<AuthService>(AuthService);

View file

@ -14,7 +14,7 @@ export class AuthService {
async spotifyLogin({ async spotifyLogin({
accessToken, accessToken,
refreshToken, refreshToken,
profile profile,
}: LoginDto): Promise<User> { }: LoginDto): Promise<User> {
const user = await this.usersService.createOrUpdate({ const user = await this.usersService.createOrUpdate({
displayName: profile.displayName, displayName: profile.displayName,
@ -22,8 +22,8 @@ export class AuthService {
spotify: { spotify: {
id: profile.id, id: profile.id,
accessToken, accessToken,
refreshToken refreshToken,
} },
}); });
return user; return user;
@ -33,7 +33,7 @@ export class AuthService {
const payload = { const payload = {
sub: user.id, sub: user.id,
name: user.displayName, name: user.displayName,
picture: user.photo picture: user.photo,
}; };
const token = await this.jwtService.signAsync(payload); const token = await this.jwtService.signAsync(payload);

View file

@ -1,3 +1,8 @@
import { createParamDecorator } from "@nestjs/common"; import { createParamDecorator, ExecutionContext } from "@nestjs/common";
export const ReqUser = createParamDecorator((data, req) => req.user); export const ReqUser = createParamDecorator<void>(
(_: void, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
}
);

View file

@ -7,13 +7,13 @@ import { AuthService } from "./auth.service";
@Injectable() @Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) { export class JwtStrategy extends PassportStrategy(Strategy) {
constructor( constructor(
private readonly config: ConfigService, private readonly authService: AuthService,
private readonly authService: AuthService config: ConfigService
) { ) {
super({ super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false, ignoreExpiration: false,
secretOrKey: config.get<string>("JWT_SECRET") secretOrKey: config.get<string>("JWT_SECRET"),
}); });
} }

View file

@ -13,13 +13,14 @@ export class SpotifyStrategy extends PassportStrategy(Strategy) {
super({ super({
clientID: config.get<string>("SPOTIFY_CLIENT_ID"), clientID: config.get<string>("SPOTIFY_CLIENT_ID"),
clientSecret: config.get<string>("SPOTIFY_CLIENT_SECRET"), clientSecret: config.get<string>("SPOTIFY_CLIENT_SECRET"),
callbackURL: `${config.get<string>("BASE_DOMAIN") || callbackURL: `${
"http://localhost:3000"}/api/v1/auth/spotify/callback`, config.get<string>("BASE_DOMAIN") || "http://localhost:3000"
}/api/v1/auth/spotify/callback`,
scope: [ scope: [
"user-read-private", "user-read-private",
"user-read-email", "user-read-email",
"user-read-recently-played" "user-read-recently-played",
] ],
}); });
} }
@ -27,7 +28,7 @@ export class SpotifyStrategy extends PassportStrategy(Strategy) {
return await this.authService.spotifyLogin({ return await this.authService.spotifyLogin({
accessToken, accessToken,
refreshToken, refreshToken,
profile profile,
}); });
} }
} }

View file

@ -19,7 +19,7 @@ export const DatabaseModule = TypeOrmModule.forRootAsync({
// Migrations // Migrations
// migrationsRun: true, // migrationsRun: true,
// migrations: [join(__dirname, "migrations", "*.{ts,js}")], // migrations: [join(__dirname, "migrations", "*.{ts,js}")],
synchronize: true synchronize: true,
}), }),
inject: [ConfigService] inject: [ConfigService],
}); });

View file

@ -3,7 +3,7 @@ import {
Entity, Entity,
Index, Index,
ManyToOne, ManyToOne,
PrimaryGeneratedColumn PrimaryGeneratedColumn,
} from "typeorm"; } from "typeorm";
import { Track } from "../music-library/track.entity"; import { Track } from "../music-library/track.entity";
import { User } from "../users/user.entity"; import { User } from "../users/user.entity";
@ -14,10 +14,10 @@ export class Listen {
@PrimaryGeneratedColumn("uuid") @PrimaryGeneratedColumn("uuid")
id: string; id: string;
@ManyToOne(type => Track) @ManyToOne((type) => Track)
track: Track; track: Track;
@ManyToOne(type => User) @ManyToOne((type) => User)
user: User; user: User;
@Column({ type: "timestamp" }) @Column({ type: "timestamp" })

View file

@ -6,6 +6,6 @@ import { ListenRepository } from "./listen.repository";
@Module({ @Module({
imports: [TypeOrmModule.forFeature([ListenRepository])], imports: [TypeOrmModule.forFeature([ListenRepository])],
providers: [ListensService], providers: [ListensService],
exports: [ListensService] exports: [ListensService],
}) })
export class ListensModule {} export class ListensModule {}

View file

@ -6,7 +6,7 @@ describe("ListensService", () => {
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [ListensService] providers: [ListensService],
}).compile(); }).compile();
service = module.get<ListensService>(ListensService); service = module.get<ListensService>(ListensService);

View file

@ -10,7 +10,7 @@ export class ListensService {
async createListen({ async createListen({
user, user,
track, track,
playedAt playedAt,
}: CreateListenDto): Promise<Listen> { }: CreateListenDto): Promise<Listen> {
const listen = this.listenRepository.create(); const listen = this.listenRepository.create();
@ -23,7 +23,7 @@ export class ListensService {
} catch (err) { } catch (err) {
if (err.code === "23505") { if (err.code === "23505") {
return this.listenRepository.findOne({ return this.listenRepository.findOne({
where: { user, track, playedAt } where: { user, track, playedAt },
}); });
} }

View file

@ -4,7 +4,7 @@ import {
Column, Column,
ManyToMany, ManyToMany,
JoinTable, JoinTable,
OneToMany OneToMany,
} from "typeorm"; } from "typeorm";
import { SpotifyLibraryDetails } from "src/sources/spotify/spotify-library-details.entity"; import { SpotifyLibraryDetails } from "src/sources/spotify/spotify-library-details.entity";
import { Artist } from "./artist.entity"; import { Artist } from "./artist.entity";
@ -18,19 +18,13 @@ export class Album {
@Column() @Column()
name: string; name: string;
@ManyToMany( @ManyToMany((type) => Artist, (artist) => artist.albums)
type => Artist,
artist => artist.albums
)
@JoinTable() @JoinTable()
artists: Artist[]; artists: Artist[];
@OneToMany( @OneToMany((type) => Track, (track) => track.album)
type => Track,
track => track.album
)
tracks: Track[]; tracks: Track[];
@Column(type => SpotifyLibraryDetails) @Column((type) => SpotifyLibraryDetails)
spotify: SpotifyLibraryDetails; spotify: SpotifyLibraryDetails;
} }

View file

@ -10,12 +10,9 @@ export class Artist {
@Column() @Column()
name: string; name: string;
@ManyToMany( @ManyToMany((type) => Album, (album) => album.artists)
type => Album,
album => album.artists
)
albums: Album[]; albums: Album[];
@Column(type => SpotifyLibraryDetails) @Column((type) => SpotifyLibraryDetails)
spotify: SpotifyLibraryDetails; spotify: SpotifyLibraryDetails;
} }

View file

@ -10,10 +10,10 @@ import { TrackRepository } from "./track.repository";
TypeOrmModule.forFeature([ TypeOrmModule.forFeature([
AlbumRepository, AlbumRepository,
ArtistRepository, ArtistRepository,
TrackRepository TrackRepository,
]) ]),
], ],
providers: [MusicLibraryService], providers: [MusicLibraryService],
exports: [MusicLibraryService] exports: [MusicLibraryService],
}) })
export class MusicLibraryModule {} export class MusicLibraryModule {}

View file

@ -6,7 +6,7 @@ describe("MusicLibraryService", () => {
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [MusicLibraryService] providers: [MusicLibraryService],
}).compile(); }).compile();
service = module.get<MusicLibraryService>(MusicLibraryService); service = module.get<MusicLibraryService>(MusicLibraryService);

View file

@ -22,7 +22,7 @@ export class MusicLibraryService {
async findArtist(query: FindArtistDto): Promise<Artist | undefined> { async findArtist(query: FindArtistDto): Promise<Artist | undefined> {
return this.artistRepository.findOne({ return this.artistRepository.findOne({
where: { spotify: { id: query.spotify.id } } where: { spotify: { id: query.spotify.id } },
}); });
} }
@ -41,7 +41,7 @@ export class MusicLibraryService {
async findAlbum(query: FindAlbumDto): Promise<Album | undefined> { async findAlbum(query: FindAlbumDto): Promise<Album | undefined> {
return this.albumRepository.findOne({ return this.albumRepository.findOne({
where: { spotify: { id: query.spotify.id } } where: { spotify: { id: query.spotify.id } },
}); });
} }
@ -59,7 +59,7 @@ export class MusicLibraryService {
async findTrack(query: FindTrackDto): Promise<Track | undefined> { async findTrack(query: FindTrackDto): Promise<Track | undefined> {
return this.trackRepository.findOne({ return this.trackRepository.findOne({
where: { spotify: { id: query.spotify.id } } where: { spotify: { id: query.spotify.id } },
}); });
} }

View file

@ -5,7 +5,7 @@ import {
JoinTable, JoinTable,
ManyToMany, ManyToMany,
ManyToOne, ManyToOne,
PrimaryGeneratedColumn PrimaryGeneratedColumn,
} from "typeorm"; } from "typeorm";
import { Album } from "./album.entity"; import { Album } from "./album.entity";
import { Artist } from "./artist.entity"; import { Artist } from "./artist.entity";
@ -18,16 +18,13 @@ export class Track {
@Column() @Column()
name: string; name: string;
@ManyToOne( @ManyToOne((type) => Album, (album) => album.tracks)
type => Album,
album => album.tracks
)
album: Album; album: Album;
@ManyToMany(type => Artist) @ManyToMany((type) => Artist)
@JoinTable() @JoinTable()
artists: Artist[]; artists: Artist[];
@Column(type => SpotifyLibraryDetails) @Column((type) => SpotifyLibraryDetails)
spotify?: SpotifyLibraryDetails; spotify?: SpotifyLibraryDetails;
} }

View file

@ -2,6 +2,6 @@ import { Module } from "@nestjs/common";
import { SpotifyModule } from "./spotify/spotify.module"; import { SpotifyModule } from "./spotify/spotify.module";
@Module({ @Module({
imports: [SpotifyModule] imports: [SpotifyModule],
}) })
export class SourcesModule {} export class SourcesModule {}

View file

@ -6,11 +6,11 @@ import { SpotifyApiService } from "./spotify-api.service";
HttpModule.registerAsync({ HttpModule.registerAsync({
useFactory: () => ({ useFactory: () => ({
timeout: 5000, timeout: 5000,
baseURL: "https://api.spotify.com/" baseURL: "https://api.spotify.com/",
}) }),
}) }),
], ],
providers: [SpotifyApiService], providers: [SpotifyApiService],
exports: [SpotifyApiService] exports: [SpotifyApiService],
}) })
export class SpotifyApiModule {} export class SpotifyApiModule {}

View file

@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from "@nestjs/testing";
import { SpotifyApiService } from './spotify-api.service'; import { SpotifyApiService } from "./spotify-api.service";
describe('SpotifyApiService', () => { describe("SpotifyApiService", () => {
let service: SpotifyApiService; let service: SpotifyApiService;
beforeEach(async () => { beforeEach(async () => {
@ -12,7 +12,7 @@ describe('SpotifyApiService', () => {
service = module.get<SpotifyApiService>(SpotifyApiService); service = module.get<SpotifyApiService>(SpotifyApiService);
}); });
it('should be defined', () => { it("should be defined", () => {
expect(service).toBeDefined(); expect(service).toBeDefined();
}); });
}); });

View file

@ -12,12 +12,12 @@ export class SpotifyApiService {
async getRecentlyPlayedTracks({ async getRecentlyPlayedTracks({
accessToken, accessToken,
lastRefreshTime lastRefreshTime,
}: SpotifyConnection): Promise<PlayHistoryObject[]> { }: SpotifyConnection): Promise<PlayHistoryObject[]> {
console.log("SpotifyApiService#getRecentlyPlayedTracks"); console.log("SpotifyApiService#getRecentlyPlayedTracks");
const parameters: { limit: number; after?: number } = { const parameters: { limit: number; after?: number } = {
limit: 50 limit: 50,
}; };
if (lastRefreshTime) { if (lastRefreshTime) {
@ -33,7 +33,7 @@ export class SpotifyApiService {
const history = await this.httpService const history = await this.httpService
.get<PagingObject<PlayHistoryObject>>(`v1/me/player/recently-played`, { .get<PagingObject<PlayHistoryObject>>(`v1/me/player/recently-played`, {
headers: { Authorization: `Bearer ${accessToken}` }, headers: { Authorization: `Bearer ${accessToken}` },
params: parameters params: parameters,
}) })
.toPromise(); .toPromise();
@ -47,7 +47,7 @@ export class SpotifyApiService {
console.log("SpotifyApiService#getArtist"); console.log("SpotifyApiService#getArtist");
const artist = await this.httpService const artist = await this.httpService
.get<ArtistObject>(`v1/artists/${spotifyID}`, { .get<ArtistObject>(`v1/artists/${spotifyID}`, {
headers: { Authorization: `Bearer ${accessToken}` } headers: { Authorization: `Bearer ${accessToken}` },
}) })
.toPromise(); .toPromise();
@ -59,7 +59,7 @@ export class SpotifyApiService {
const album = await this.httpService const album = await this.httpService
.get<AlbumObject>(`v1/albums/${spotifyID}`, { .get<AlbumObject>(`v1/albums/${spotifyID}`, {
headers: { Authorization: `Bearer ${accessToken}` } headers: { Authorization: `Bearer ${accessToken}` },
}) })
.toPromise(); .toPromise();
@ -72,7 +72,7 @@ export class SpotifyApiService {
const track = await this.httpService const track = await this.httpService
.get<TrackObject>(`v1/tracks/${spotifyID}`, { .get<TrackObject>(`v1/tracks/${spotifyID}`, {
headers: { Authorization: `Bearer ${accessToken}` } headers: { Authorization: `Bearer ${accessToken}` },
}) })
.toPromise(); .toPromise();

View file

@ -6,11 +6,11 @@ import { SpotifyAuthService } from "./spotify-auth.service";
HttpModule.registerAsync({ HttpModule.registerAsync({
useFactory: () => ({ useFactory: () => ({
timeout: 5000, timeout: 5000,
baseURL: "https://accounts.spotify.com/" baseURL: "https://accounts.spotify.com/",
}) }),
}) }),
], ],
providers: [SpotifyAuthService], providers: [SpotifyAuthService],
exports: [SpotifyAuthService] exports: [SpotifyAuthService],
}) })
export class SpotifyAuthModule {} export class SpotifyAuthModule {}

View file

@ -23,8 +23,8 @@ export class SpotifyAuthService {
{ {
auth: { auth: {
username: this.clientID, username: this.clientID,
password: this.clientSecret password: this.clientSecret,
} },
} }
) )
.toPromise(); .toPromise();
@ -40,8 +40,8 @@ export class SpotifyAuthService {
{ {
auth: { auth: {
username: this.clientID, username: this.clientID,
password: this.clientSecret password: this.clientSecret,
} },
} }
) )
.toPromise(); .toPromise();

View file

@ -12,8 +12,8 @@ import { SpotifyAuthModule } from "./spotify-auth/spotify-auth.module";
ListensModule, ListensModule,
MusicLibraryModule, MusicLibraryModule,
SpotifyApiModule, SpotifyApiModule,
SpotifyAuthModule SpotifyAuthModule,
], ],
providers: [SpotifyService] providers: [SpotifyService],
}) })
export class SpotifyModule {} export class SpotifyModule {}

View file

@ -6,7 +6,7 @@ describe("SpotifyService", () => {
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [SpotifyService] providers: [SpotifyService],
}).compile(); }).compile();
service = module.get<SpotifyService>(SpotifyService); service = module.get<SpotifyService>(SpotifyService);

View file

@ -51,7 +51,7 @@ export class SpotifyService {
); );
await this.usersService.updateSpotifyConnection(user, { await this.usersService.updateSpotifyConnection(user, {
...user.spotify, ...user.spotify,
accessToken accessToken,
}); });
await this.processUser(user, false); await this.processUser(user, false);
} }
@ -62,13 +62,13 @@ export class SpotifyService {
} }
await Promise.all( await Promise.all(
playHistory.map(async history => { playHistory.map(async (history) => {
const track = await this.importTrack(history.track.id); const track = await this.importTrack(history.track.id);
this.listensService.createListen({ this.listensService.createListen({
user, user,
track, track,
playedAt: new Date(history.played_at) playedAt: new Date(history.played_at),
}); });
console.log( console.log(
@ -79,19 +79,19 @@ export class SpotifyService {
const newestPlayTime = new Date( const newestPlayTime = new Date(
playHistory playHistory
.map(history => history.played_at) .map((history) => history.played_at)
.sort() .sort()
.pop() .pop()
); );
console.log("newestPlayTime", { console.log("newestPlayTime", {
newestPlayTime, newestPlayTime,
times: playHistory.map(history => history.played_at).sort() times: playHistory.map((history) => history.played_at).sort(),
}); });
this.usersService.updateSpotifyConnection(user, { this.usersService.updateSpotifyConnection(user, {
...user.spotify, ...user.spotify,
lastRefreshTime: newestPlayTime lastRefreshTime: newestPlayTime,
}); });
} }
@ -100,7 +100,7 @@ export class SpotifyService {
retryOnExpiredToken: boolean = true retryOnExpiredToken: boolean = true
): Promise<Track> { ): Promise<Track> {
const track = await this.musicLibraryService.findTrack({ const track = await this.musicLibraryService.findTrack({
spotify: { id: spotifyID } spotify: { id: spotifyID },
}); });
if (track) { if (track) {
return track; return track;
@ -129,7 +129,7 @@ export class SpotifyService {
spotifyTrack.artists.map(({ id: artistID }) => spotifyTrack.artists.map(({ id: artistID }) =>
this.importArtist(artistID) this.importArtist(artistID)
) )
) ),
]); ]);
return this.musicLibraryService.createTrack({ return this.musicLibraryService.createTrack({
@ -140,8 +140,8 @@ export class SpotifyService {
id: spotifyTrack.id, id: spotifyTrack.id,
uri: spotifyTrack.uri, uri: spotifyTrack.uri,
type: spotifyTrack.type, type: spotifyTrack.type,
href: spotifyTrack.href href: spotifyTrack.href,
} },
}); });
} }
@ -150,7 +150,7 @@ export class SpotifyService {
retryOnExpiredToken: boolean = true retryOnExpiredToken: boolean = true
): Promise<Album> { ): Promise<Album> {
const album = await this.musicLibraryService.findAlbum({ const album = await this.musicLibraryService.findAlbum({
spotify: { id: spotifyID } spotify: { id: spotifyID },
}); });
if (album) { if (album) {
return album; return album;
@ -186,8 +186,8 @@ export class SpotifyService {
id: spotifyAlbum.id, id: spotifyAlbum.id,
uri: spotifyAlbum.uri, uri: spotifyAlbum.uri,
type: spotifyAlbum.type, type: spotifyAlbum.type,
href: spotifyAlbum.href href: spotifyAlbum.href,
} },
}); });
} }
@ -196,7 +196,7 @@ export class SpotifyService {
retryOnExpiredToken: boolean = true retryOnExpiredToken: boolean = true
): Promise<Artist> { ): Promise<Artist> {
const artist = await this.musicLibraryService.findArtist({ const artist = await this.musicLibraryService.findArtist({
spotify: { id: spotifyID } spotify: { id: spotifyID },
}); });
if (artist) { if (artist) {
return artist; return artist;
@ -225,8 +225,8 @@ export class SpotifyService {
id: spotifyArtist.id, id: spotifyArtist.id,
uri: spotifyArtist.uri, uri: spotifyArtist.uri,
type: spotifyArtist.type, type: spotifyArtist.type,
href: spotifyArtist.href href: spotifyArtist.href,
} },
}); });
} }

View file

@ -12,6 +12,6 @@ export class User {
@Column({ nullable: true }) @Column({ nullable: true })
photo?: string; photo?: string;
@Column(type => SpotifyConnection) @Column((type) => SpotifyConnection)
spotify: SpotifyConnection; spotify: SpotifyConnection;
} }

View file

@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from "@nestjs/testing";
import { UsersController } from './users.controller'; import { UsersController } from "./users.controller";
describe('Users Controller', () => { describe("Users Controller", () => {
let controller: UsersController; let controller: UsersController;
beforeEach(async () => { beforeEach(async () => {
@ -12,7 +12,7 @@ describe('Users Controller', () => {
controller = module.get<UsersController>(UsersController); controller = module.get<UsersController>(UsersController);
}); });
it('should be defined', () => { it("should be defined", () => {
expect(controller).toBeDefined(); expect(controller).toBeDefined();
}); });
}); });

View file

@ -11,7 +11,7 @@ export class UsersController {
return { return {
id: user.id, id: user.id,
displayName: user.displayName, displayName: user.displayName,
photo: user.photo photo: user.photo,
}; };
} }
} }

View file

@ -2,12 +2,12 @@ import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm"; import { TypeOrmModule } from "@nestjs/typeorm";
import { UserRepository } from "./user.repository"; import { UserRepository } from "./user.repository";
import { UsersService } from "./users.service"; import { UsersService } from "./users.service";
import { UsersController } from './users.controller'; import { UsersController } from "./users.controller";
@Module({ @Module({
imports: [TypeOrmModule.forFeature([UserRepository])], imports: [TypeOrmModule.forFeature([UserRepository])],
providers: [UsersService], providers: [UsersService],
exports: [UsersService], exports: [UsersService],
controllers: [UsersController] controllers: [UsersController],
}) })
export class UsersModule {} export class UsersModule {}

View file

@ -6,7 +6,7 @@ describe("UsersService", () => {
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [UsersService] providers: [UsersService],
}).compile(); }).compile();
service = module.get<UsersService>(UsersService); service = module.get<UsersService>(UsersService);

View file

@ -24,14 +24,14 @@ export class UsersService {
async createOrUpdate(data: CreateOrUpdateDto): Promise<User> { async createOrUpdate(data: CreateOrUpdateDto): Promise<User> {
let user = await this.userRepository.findOne({ let user = await this.userRepository.findOne({
where: { spotify: { id: data.spotify.id } } where: { spotify: { id: data.spotify.id } },
}); });
if (!user) { if (!user) {
user = this.userRepository.create({ user = this.userRepository.create({
spotify: { spotify: {
id: data.spotify.id id: data.spotify.id,
} },
}); });
} }