Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions apps/server/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import tsParser from '@typescript-eslint/parser';
import eslintConfigPrettier from 'eslint-config-prettier';
import pluginJest from 'eslint-plugin-jest';
import globals from 'globals';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js'
import tsParser from '@typescript-eslint/parser'
import eslintConfigPrettier from 'eslint-config-prettier'
import pluginJest from 'eslint-plugin-jest'
import globals from 'globals'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
})

export default [
{
Expand Down Expand Up @@ -70,4 +70,4 @@ export default [
},

eslintConfigPrettier,
];
]
5 changes: 3 additions & 2 deletions apps/server/prettier.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
const config = {
singleQuote: true,
};
semi: false,
}

export default config;
export default config
14 changes: 7 additions & 7 deletions apps/server/src/app/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Controller, Get } from '@nestjs/common';
import { GitHubApiService } from '../modules/api/github-api/github-api.service';
import { AppService } from './app.service';
import { Controller, Get } from '@nestjs/common'
import { GitHubApiService } from '../modules/api/github-api/github-api.service'
import { AppService } from './app.service'

@Controller('/api/app')
export class AppController {
Expand All @@ -11,12 +11,12 @@ export class AppController {

@Get('/status')
async getAppStatus() {
return JSON.stringify(await this.appService.getAppVersionStatus());
return JSON.stringify(await this.appService.getAppVersionStatus())
}

@Get('/timezone')
async getAppTimezone() {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
return Intl.DateTimeFormat().resolvedOptions().timeZone
}

@Get('/releases')
Expand All @@ -25,7 +25,7 @@ export class AppController {
'maintainerr',
'maintainerr',
10,
);
return releases || [];
)
return releases || []
}
}
76 changes: 38 additions & 38 deletions apps/server/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { Module, OnModuleInit } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { ServeStaticModule } from '@nestjs/serve-static';
import { TypeOrmModule } from '@nestjs/typeorm';
import { GracefulShutdownModule } from '@tygra/nestjs-graceful-shutdown';
import { ZodValidationPipe } from 'nestjs-zod';
import { join } from 'path';
import { ExternalApiModule } from '../modules/api/external-api/external-api.module';
import { GitHubApiModule } from '../modules/api/github-api/github-api.module';
import { MediaServerFactory } from '../modules/api/media-server/media-server.factory';
import { MediaServerModule } from '../modules/api/media-server/media-server.module';
import { PlexApiModule } from '../modules/api/plex-api/plex-api.module';
import { SeerrApiModule } from '../modules/api/seerr-api/seerr-api.module';
import { SeerrApiService } from '../modules/api/seerr-api/seerr-api.service';
import { ServarrApiModule } from '../modules/api/servarr-api/servarr-api.module';
import { TautulliApiModule } from '../modules/api/tautulli-api/tautulli-api.module';
import { TautulliApiService } from '../modules/api/tautulli-api/tautulli-api.service';
import { TmdbApiModule } from '../modules/api/tmdb-api/tmdb.module';
import { CollectionsModule } from '../modules/collections/collections.module';
import { EventsModule } from '../modules/events/events.module';
import { LogsModule } from '../modules/logging/logs.module';
import { NotificationsModule } from '../modules/notifications/notifications.module';
import { NotificationService } from '../modules/notifications/notifications.service';
import { RulesModule } from '../modules/rules/rules.module';
import { SettingsModule } from '../modules/settings/settings.module';
import { SettingsService } from '../modules/settings/settings.service';
import { StatsModule } from '../modules/stats/stats.module';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import ormConfig from './config/typeOrmConfig';
import { Module, OnModuleInit } from '@nestjs/common'
import { APP_PIPE } from '@nestjs/core'
import { EventEmitterModule } from '@nestjs/event-emitter'
import { ServeStaticModule } from '@nestjs/serve-static'
import { TypeOrmModule } from '@nestjs/typeorm'
import { GracefulShutdownModule } from '@tygra/nestjs-graceful-shutdown'
import { ZodValidationPipe } from 'nestjs-zod'
import { join } from 'path'
import { ExternalApiModule } from '../modules/api/external-api/external-api.module'
import { GitHubApiModule } from '../modules/api/github-api/github-api.module'
import { MediaServerFactory } from '../modules/api/media-server/media-server.factory'
import { MediaServerModule } from '../modules/api/media-server/media-server.module'
import { PlexApiModule } from '../modules/api/plex-api/plex-api.module'
import { SeerrApiModule } from '../modules/api/seerr-api/seerr-api.module'
import { SeerrApiService } from '../modules/api/seerr-api/seerr-api.service'
import { ServarrApiModule } from '../modules/api/servarr-api/servarr-api.module'
import { TautulliApiModule } from '../modules/api/tautulli-api/tautulli-api.module'
import { TautulliApiService } from '../modules/api/tautulli-api/tautulli-api.service'
import { TmdbApiModule } from '../modules/api/tmdb-api/tmdb.module'
import { CollectionsModule } from '../modules/collections/collections.module'
import { EventsModule } from '../modules/events/events.module'
import { LogsModule } from '../modules/logging/logs.module'
import { NotificationsModule } from '../modules/notifications/notifications.module'
import { NotificationService } from '../modules/notifications/notifications.service'
import { RulesModule } from '../modules/rules/rules.module'
import { SettingsModule } from '../modules/settings/settings.module'
import { SettingsService } from '../modules/settings/settings.service'
import { StatsModule } from '../modules/stats/stats.module'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import ormConfig from './config/typeOrmConfig'

@Module({
imports: [
Expand All @@ -55,7 +55,7 @@ import ormConfig from './config/typeOrmConfig';
ServeStaticModule.forRootAsync({
useFactory: () => {
if (process.env.NODE_ENV !== 'production') {
return [];
return []
}

return [
Expand All @@ -64,7 +64,7 @@ import ormConfig from './config/typeOrmConfig';
serveRoot: process.env.BASE_PATH || undefined,
exclude: ['/api/{*path}'],
},
];
]
},
}),
],
Expand All @@ -87,15 +87,15 @@ export class AppModule implements OnModuleInit {
) {}
async onModuleInit() {
// Initialize modules requiring settings
await this.settings.init();
await this.settings.init()

// Initialize configured media server (Plex or Jellyfin)
await this.mediaServerFactory.initialize();
await this.mediaServerFactory.initialize()

this.seerrApi.init();
this.tautulliApi.init();
this.seerrApi.init()
this.tautulliApi.init()

// intialize notification agents
await this.notificationService.registerConfiguredAgents();
await this.notificationService.registerConfiguredAgents()
}
}
42 changes: 21 additions & 21 deletions apps/server/src/app/app.service.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
import { type VersionResponse } from '@maintainerr/contracts';
import { Injectable } from '@nestjs/common';
import { GitHubApiService } from '../modules/api/github-api/github-api.service';
import { MaintainerrLogger } from '../modules/logging/logs.service';
import { type VersionResponse } from '@maintainerr/contracts'
import { Injectable } from '@nestjs/common'
import { GitHubApiService } from '../modules/api/github-api/github-api.service'
import { MaintainerrLogger } from '../modules/logging/logs.service'

@Injectable()
export class AppService {
constructor(
private readonly githubApi: GitHubApiService,
private readonly logger: MaintainerrLogger,
) {
logger.setContext(AppService.name);
logger.setContext(AppService.name)
}

async getAppVersionStatus(): Promise<VersionResponse> {
try {
const packageVersion = process.env.npm_package_version
? process.env.npm_package_version
: '0.0.1';
: '0.0.1'

const versionTag = process.env.VERSION_TAG
? process.env.VERSION_TAG
: 'develop';
: 'develop'

const calculatedVersion =
versionTag !== 'stable'
? process.env.GIT_SHA
? `${versionTag}-${process.env.GIT_SHA.substring(0, 7)}`
: `${versionTag}-`
: `${packageVersion}`;
: `${packageVersion}`

const local = process.env.NODE_ENV !== 'production';
const local = process.env.NODE_ENV !== 'production'

return {
status: 1,
Expand All @@ -39,15 +39,15 @@ export class AppService {
packageVersion,
versionTag,
),
};
}
} catch (err) {
this.logger.error(`Couldn't fetch app version status`, err);
this.logger.error(`Couldn't fetch app version status`, err)
return {
status: 0,
version: '0.0.1',
commitTag: '',
updateAvailable: false,
};
}
}
}

Expand All @@ -56,33 +56,33 @@ export class AppService {
const githubResp = await this.githubApi.getLatestRelease(
'Maintainerr',
'Maintainerr',
);
)
if (githubResp && githubResp.tag_name) {
const transformedLocalVersion = currentVersion
.replace('v', '')
.replace('.', '');
.replace('.', '')

const transformedGithubVersion = githubResp.tag_name
.replace('v', '')
.replace('.', '');
.replace('.', '')

return transformedGithubVersion > transformedLocalVersion;
return transformedGithubVersion > transformedLocalVersion
}
this.logger.warn(`Couldn't fetch latest release version from GitHub`);
return false;
this.logger.warn(`Couldn't fetch latest release version from GitHub`)
return false
} else {
// in case of develop, compare SHA's
if (process.env.GIT_SHA) {
const githubResp = await this.githubApi.getCommit(
'Maintainerr',
'Maintainerr',
'main',
);
)
if (githubResp && githubResp.sha) {
return githubResp.sha !== process.env.GIT_SHA;
return githubResp.sha !== process.env.GIT_SHA
}
}
}
return false;
return false
}
}
6 changes: 3 additions & 3 deletions apps/server/src/app/config/typeOrmConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { TypeOrmModuleOptions } from '@nestjs/typeorm'

const ormConfig: TypeOrmModuleOptions = {
type: 'better-sqlite3',
Expand All @@ -14,5 +14,5 @@ const ormConfig: TypeOrmModuleOptions = {
: ['./dist/database/migrations/**/*{.js,.ts}'],
autoLoadEntities: true,
migrationsRun: true,
};
export default ormConfig;
}
export default ormConfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { MigrationInterface, QueryRunner } from 'typeorm'

export class InitialMigration1674487252453 implements MigrationInterface {
name = 'InitialMigration1674487252453';
name = 'InitialMigration1674487252453'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE IF NOT EXISTS "settings" (
Expand All @@ -26,20 +26,20 @@ export class InitialMigration1674487252453 implements MigrationInterface {
"collection_handler_job_cron" varchar NOT NULL DEFAULT ('0 0-23/12 * * *'),
"rules_handler_job_cron" varchar NOT NULL DEFAULT ('0 0-23/8 * * *'),
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "community_rule_karma" (
"id" integer NOT NULL,
"community_rule_id" integer NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "exclusion" (
"id" integer NOT NULL,
"plexId" integer NOT NULL,
"ruleGroupId" integer,
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "collection_media" (
"id" integer NOT NULL,
Expand All @@ -51,7 +51,7 @@ export class InitialMigration1674487252453 implements MigrationInterface {
"isManual" boolean DEFAULT (0),
CONSTRAINT "FK_604b0cd0f85150923289b7f2c19" FOREIGN KEY("collectionId") REFERENCES "collection"("id") ON DELETE CASCADE ON UPDATE NO ACTION,
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "rules" (
"id" integer NOT NULL,
Expand All @@ -61,7 +61,7 @@ export class InitialMigration1674487252453 implements MigrationInterface {
"isActive" boolean NOT NULL DEFAULT (1),
CONSTRAINT "FK_bb013935b8859281ad67e311d19" FOREIGN KEY("ruleGroupId") REFERENCES "rule_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION,
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "rule_group" (
"id" integer NOT NULL,
Expand All @@ -73,7 +73,7 @@ export class InitialMigration1674487252453 implements MigrationInterface {
CONSTRAINT "FK_9c757efe456ec36319ef10e9648" FOREIGN KEY("collectionId") REFERENCES "collection"("id") ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT "REL_9c757efe456ec36319ef10e964" UNIQUE("collectionId"),
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)

await queryRunner.query(`CREATE TABLE IF NOT EXISTS "collection" (
"id" integer NOT NULL,
Expand All @@ -87,16 +87,16 @@ export class InitialMigration1674487252453 implements MigrationInterface {
"deleteAfterDays" integer,
"type" integer NOT NULL DEFAULT (1),
PRIMARY KEY("id" AUTOINCREMENT)
);`);
);`)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "settings";`);
await queryRunner.query(`DROP TABLE "community_rule_karma";`);
await queryRunner.query(`DROP TABLE "exclusion";`);
await queryRunner.query(`DROP TABLE "collection_media";`);
await queryRunner.query(`DROP TABLE "rules";`);
await queryRunner.query(`DROP TABLE "rule_group";`);
await queryRunner.query(`DROP TABLE "collection";`);
await queryRunner.query(`DROP TABLE "settings";`)
await queryRunner.query(`DROP TABLE "community_rule_karma";`)
await queryRunner.query(`DROP TABLE "exclusion";`)
await queryRunner.query(`DROP TABLE "collection_media";`)
await queryRunner.query(`DROP TABLE "rules";`)
await queryRunner.query(`DROP TABLE "rule_group";`)
await queryRunner.query(`DROP TABLE "collection";`)
}
}
Loading