feat: add development database

This commit is contained in:
Aleksi Lassila
2025-02-11 19:16:25 +02:00
parent ad2bad9a27
commit b46a65a93c
10 changed files with 53 additions and 32 deletions

View File

@@ -3,7 +3,7 @@ import { DataSource } from 'typeorm';
export default new DataSource({
type: 'sqlite',
database: './config/reiverr.sqlite',
database: `./config/reiverr${ENV === 'development' ? '.dev' : ''}.sqlite`,
entities: ['dist/**/*.entity.js'],
migrations: ['dist/migrations/*.js'],
synchronize: ENV === 'development',

View File

@@ -9,7 +9,7 @@
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:dev": "set NODE_ENV=development&& nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "npm run typeorm:run-migrations && node dist/src/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
@@ -96,4 +96,4 @@
"plugins/jellyfin.plugin",
"plugins/torrent-stream.plugin"
]
}
}

View File

@@ -1,7 +1,7 @@
export const NODE_ENV = process.env.NODE_ENV || 'development';
export const ENV = process.env.NODE_ENV || 'production';
export const JWT_SECRET =
process.env.SECRET ||
(NODE_ENV === 'development'
(ENV === 'development'
? 'secret'
: Math.random().toString(36).substring(2, 15));
export const TMDB_API_KEY =
@@ -9,7 +9,6 @@ export const TMDB_API_KEY =
'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0YTZiMDIxZTE5Y2YxOTljMTM1NGFhMGRiMDZiOTkzMiIsInN1YiI6IjY0ODYzYWRmMDI4ZjE0MDExZTU1MDkwMiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.yyMkZlhGOGBHtw1yvpBVUUHhu7IKVYho49MvNNKt_wY';
export const ADMIN_USERNAME = process.env.ADMIN_USERNAME;
export const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD;
export const ENV = process.env.NODE_ENV || 'development';
export const TMDB_CACHE_TTL = Number.isNaN(Number(process.env.TMDB_CACHE_TTL))
? 1000 * 60 * 60 * 24 * 3 // 3 days
: Number(process.env.TMDB_CACHE_TTL);

View File

@@ -4,7 +4,7 @@ import 'reflect-metadata';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import * as fs from 'fs';
import { UsersService } from './users/users.service';
import { ADMIN_PASSWORD, ADMIN_USERNAME, ENV, NODE_ENV } from './consts';
import { ADMIN_PASSWORD, ADMIN_USERNAME, ENV } from './consts';
import { json, urlencoded } from 'express';
// import * as proxy from 'express-http-proxy';
require('ts-node/register'); // For importing plugins
@@ -49,7 +49,7 @@ async function bootstrap() {
await app.listen(9494);
console.log(
`Application is running on: ${await app.getUrl()} in ${NODE_ENV} mode`,
`Application is running on: ${await app.getUrl()} in ${ENV} mode`,
);
}

View File

@@ -23,7 +23,7 @@ export class UserDto extends OmitType(User, [
// pluginSettings: entity.pluginSettings,
};
delete out.password;
delete (out as any).password;
return out;
}

View File

@@ -107,6 +107,10 @@ export class UsersController {
else throw new InternalServerErrorException();
});
if (!user) {
throw new InternalServerErrorException();
}
return UserDto.fromEntity(user);
}
@@ -132,6 +136,10 @@ export class UsersController {
} else throw new InternalServerErrorException();
});
if (!updated) {
throw new InternalServerErrorException();
}
return UserDto.fromEntity(updated);
}

View File

@@ -33,30 +33,34 @@ export class UsersService {
);
}
async findOne(id: string): Promise<User> {
return this.userRepository
.findOne({
where: { id },
relations: {
mediaSources: true,
},
})
.then((u) => this.filterMediaSources(u));
async findOne(id: string): Promise<User | undefined> {
const user = await this.userRepository.findOne({
where: { id },
relations: {
mediaSources: true,
},
});
if (!user) return undefined;
return this.filterMediaSources(user);
}
async findOneByName(name: string): Promise<User> {
return this.userRepository
.findOne({
where: { name },
relations: {
mediaSources: true,
},
})
.then((u) => this.filterMediaSources(u));
async findOneByName(name: string): Promise<User | undefined> {
const user = await this.userRepository.findOne({
where: { name },
relations: {
mediaSources: true,
},
});
if (!user) return undefined;
return this.filterMediaSources(user);
}
// The rest
async create(userCreateDto: CreateUserDto): Promise<User> {
async create(userCreateDto: CreateUserDto): Promise<User | undefined> {
if (!userCreateDto.name) throw UserServiceError.UsernameRequired;
const user = this.userRepository.create();
@@ -67,7 +71,7 @@ export class UsersService {
try {
user.profilePicture = Buffer.from(
userCreateDto.profilePicture.split(';base64,').pop() as string,
userCreateDto.profilePicture?.split(';base64,').pop() as string,
'base64',
);
} catch (e) {
@@ -82,7 +86,7 @@ export class UsersService {
userId: string,
callerUser: User,
updateUserDto: UpdateUserDto,
): Promise<User> {
): Promise<User | undefined> {
const user = await this.userRepository.findOne({ where: { id: userId } });
if (!user) throw new Error('Update user: User not found');

View File

@@ -10,5 +10,7 @@ services:
build:
context: .
target: development
environment:
- NODE_ENV=development
ports:
- 5173:5173

View File

@@ -76,7 +76,11 @@
<DetachedPage class="flex flex-col relative">
<div class="h-[calc(100vh-12rem)] flex px-32">
<TmdbMoviesHeroShowcase movies={recommendedMovies.then(({ top10 }) => top10)} />
<TmdbMoviesHeroShowcase
movies={recommendedMovies.then(({ top10 }) =>
top10.length ? top10 : upcomingMovies.then((m) => m.slice(0, 10))
)}
/>
</div>
<div class="my-16 space-y-8 relative z-10">
{#if $libraryContinueWatching.length}

View File

@@ -70,7 +70,11 @@
<DetachedPage class="flex flex-col relative">
<div class="h-[calc(100vh-12rem)] flex px-32">
<TmdbSeriesHeroShowcase series={recommendations.then(({ top10 }) => top10)} />
<TmdbSeriesHeroShowcase
series={recommendations.then(({ top10 }) =>
top10.length ? top10 : upcomingSeries.then((s) => s.slice(0, 10))
)}
/>
</div>
<div class="my-16 space-y-8 relative z-10">
{#if $libraryContinueWatching.length}