fix(pcd): fix up temp types until i refactor them properly

This commit is contained in:
Sam Chau
2026-01-27 22:52:59 +10:30
parent 8a75f718b6
commit 1c7e063b9b
13 changed files with 48 additions and 668 deletions

View File

@@ -12,7 +12,7 @@ import {
disableDatabaseInstance,
databaseInstancesQueries
} from '$db/queries/databaseInstances.ts';
import type { PCDDatabase } from './schema.ts';
import type { PCDDatabase } from '$shared/pcd/types.ts';
import { triggerSyncs } from '$sync/processor.ts';
/**

View File

@@ -3,7 +3,7 @@
*/
import type { PCDCache } from '../../cache.ts';
import type { Tag } from '../../types.ts';
import type { Tag } from '$shared/pcd/display.ts';
import type { CustomFormatTableRow, ConditionRef } from './types.ts';
/**

View File

@@ -2,7 +2,7 @@
* Custom Format query-specific types
*/
import type { Tag } from '../../types.ts';
import type { Tag } from '$shared/pcd/display.ts';
/** Condition reference for display */
export interface ConditionRef {

View File

@@ -52,6 +52,7 @@ export async function list(cache: PCDCache) {
// Build the final result
return entities.map((entity) => ({
...entity,
type: entity.type as 'movie' | 'series',
releases: (releasesMap.get(`${entity.type}-${entity.tmdb_id}`) || []).map((r) => ({
id: r.id,
title: r.title,

View File

@@ -18,7 +18,7 @@ export async function list(cache: PCDCache): Promise<MediaSettingsListItem[]> {
for (const row of radarrRows) {
items.push({
name: row.name,
name: row.name!,
arr_type: 'radarr',
propers_repacks: row.propers_repacks,
enable_media_info: row.enable_media_info === 1,
@@ -28,7 +28,7 @@ export async function list(cache: PCDCache): Promise<MediaSettingsListItem[]> {
for (const row of sonarrRows) {
items.push({
name: row.name,
name: row.name!,
arr_type: 'sonarr',
propers_repacks: row.propers_repacks,
enable_media_info: row.enable_media_info === 1,
@@ -54,7 +54,7 @@ export async function getRadarrByName(
if (!row) return null;
return {
name: row.name,
name: row.name!,
propers_repacks: row.propers_repacks as PropersRepacks,
enable_media_info: row.enable_media_info === 1
};
@@ -75,7 +75,7 @@ export async function getSonarrByName(
if (!row) return null;
return {
name: row.name,
name: row.name!,
propers_repacks: row.propers_repacks as PropersRepacks,
enable_media_info: row.enable_media_info === 1
};

View File

@@ -5,7 +5,7 @@
import type { PCDCache } from '../../../cache.ts';
import { writeOperation, type OperationLayer } from '../../../writer.ts';
import type { RadarrColonReplacementFormat, ColonReplacementFormat, MultiEpisodeStyle } from '$lib/shared/mediaManagement.ts';
import { radarrColonReplacementToDb, colonReplacementToDb, multiEpisodeStyleToDb } from '$lib/shared/mediaManagement.ts';
import { colonReplacementToDb, multiEpisodeStyleToDb } from '$lib/shared/mediaManagement.ts';
export interface CreateRadarrNamingInput {
name: string;
@@ -46,7 +46,7 @@ export async function createRadarrNaming(options: CreateRadarrNamingOptions) {
movie_format: input.movieFormat,
movie_folder_format: input.movieFolderFormat,
replace_illegal_characters: input.replaceIllegalCharacters ? 1 : 0,
colon_replacement_format: radarrColonReplacementToDb(input.colonReplacementFormat)
colon_replacement_format: input.colonReplacementFormat
})
.compile();

View File

@@ -3,14 +3,17 @@
*/
import type { PCDCache } from '../../../cache.ts';
import type { RadarrNaming, SonarrNaming } from '$lib/shared/mediaManagement.ts';
import {
radarrColonReplacementFromDb,
colonReplacementFromDb,
multiEpisodeStyleFromDb
import type {
RadarrNaming,
SonarrNaming,
RadarrColonReplacementFormat
} from '$lib/shared/mediaManagement.ts';
import { colonReplacementFromDb, multiEpisodeStyleFromDb } from '$lib/shared/mediaManagement.ts';
import type { NamingListItem } from './types.ts';
// Note: name is PRIMARY KEY so never null, but Kysely types it as nullable
// because the generator doesn't detect non-INTEGER primary keys
export async function list(cache: PCDCache): Promise<NamingListItem[]> {
const db = cache.kb;
@@ -23,7 +26,7 @@ export async function list(cache: PCDCache): Promise<NamingListItem[]> {
for (const row of radarrRows) {
items.push({
name: row.name,
name: row.name!,
arr_type: 'radarr',
rename: row.rename === 1,
updated_at: row.updated_at
@@ -32,7 +35,7 @@ export async function list(cache: PCDCache): Promise<NamingListItem[]> {
for (const row of sonarrRows) {
items.push({
name: row.name,
name: row.name!,
arr_type: 'sonarr',
rename: row.rename === 1,
updated_at: row.updated_at
@@ -64,12 +67,12 @@ export async function getRadarrByName(
if (!row) return null;
return {
name: row.name,
name: row.name!,
rename: row.rename === 1,
movie_format: row.movie_format,
movie_folder_format: row.movie_folder_format,
replace_illegal_characters: row.replace_illegal_characters === 1,
colon_replacement_format: radarrColonReplacementFromDb(row.colon_replacement_format as number)
colon_replacement_format: row.colon_replacement_format as RadarrColonReplacementFormat
};
}
@@ -100,7 +103,7 @@ export async function getSonarrByName(
if (!row) return null;
return {
name: row.name,
name: row.name!,
rename: row.rename === 1,
standard_episode_format: row.standard_episode_format,
daily_episode_format: row.daily_episode_format,
@@ -108,8 +111,8 @@ export async function getSonarrByName(
series_folder_format: row.series_folder_format,
season_folder_format: row.season_folder_format,
replace_illegal_characters: row.replace_illegal_characters === 1,
colon_replacement_format: colonReplacementFromDb(row.colon_replacement_format as number),
colon_replacement_format: colonReplacementFromDb(row.colon_replacement_format),
custom_colon_replacement_format: row.custom_colon_replacement_format,
multi_episode_style: multiEpisodeStyleFromDb(row.multi_episode_style as number)
multi_episode_style: multiEpisodeStyleFromDb(row.multi_episode_style)
};
}

View File

@@ -4,8 +4,8 @@
import type { PCDCache } from '../../../cache.ts';
import { writeOperation, type OperationLayer } from '../../../writer.ts';
import type { RadarrColonReplacementFormat, ColonReplacementFormat, MultiEpisodeStyle } from '$lib/shared/mediaManagement.ts';
import { radarrColonReplacementToDb, colonReplacementToDb, multiEpisodeStyleToDb } from '$lib/shared/mediaManagement.ts';
import type { ColonReplacementFormat, MultiEpisodeStyle, RadarrColonReplacementFormat } from '$lib/shared/mediaManagement.ts';
import { colonReplacementToDb, multiEpisodeStyleToDb } from '$lib/shared/mediaManagement.ts';
export interface UpdateRadarrNamingInput {
name: string;
@@ -49,7 +49,7 @@ export async function updateRadarrNaming(options: UpdateRadarrNamingOptions) {
movie_format: input.movieFormat,
movie_folder_format: input.movieFolderFormat,
replace_illegal_characters: input.replaceIllegalCharacters ? 1 : 0,
colon_replacement_format: radarrColonReplacementToDb(input.colonReplacementFormat)
colon_replacement_format: input.colonReplacementFormat
})
.where('name', '=', currentName)
.compile();

View File

@@ -3,7 +3,7 @@
*/
import type { PCDCache } from '../../cache.ts';
import type { Tag } from '../../types.ts';
import type { Tag } from '$shared/pcd/display.ts';
import type {
QualityProfileTableRow,
QualityItem,

View File

@@ -3,7 +3,7 @@
*/
import type { PCDCache } from '../../cache.ts';
import type { QualityProfileScoring } from '../../types.ts';
import type { QualityProfileScoring } from './types.ts';
/**
* Get quality profile scoring data

View File

@@ -2,7 +2,7 @@
* Quality Profile query-specific types
*/
import type { Tag } from '../../types.ts';
import type { Tag } from '$shared/pcd/display.ts';
// ============================================================================
// INTERNAL TYPES (used within queries)
@@ -79,6 +79,23 @@ export interface QualityProfileQualities {
groups: QualityGroup[];
}
/** Custom format scoring entry */
export interface CustomFormatScoring {
name: string;
tags: string[];
scores: Record<string, number | null>;
}
/** Quality profile scoring data for the scoring page */
export interface QualityProfileScoring {
databaseId: number;
arrTypes: string[];
customFormats: CustomFormatScoring[];
minimum_custom_format_score: number;
upgrade_until_score: number;
upgrade_score_increment: number;
}
/** Quality profile data for table view with all relationships */
export interface QualityProfileTableRow {
// Basic info

View File

@@ -1,365 +0,0 @@
/**
* Kysely Database Schema Types for PCD (Profilarr Compliant Database)
* Auto-generated columns use Generated<T>
*/
import type { Generated } from 'kysely';
// ============================================================================
// CORE ENTITY TABLES
// ============================================================================
export interface TagsTable {
id: Generated<number>;
name: string;
created_at: Generated<string>;
}
export interface LanguagesTable {
id: Generated<number>;
name: string;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface RegularExpressionsTable {
id: Generated<number>;
name: string;
pattern: string;
regex101_id: string | null;
description: string | null;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface QualitiesTable {
id: Generated<number>;
name: string;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface QualityApiMappingsTable {
quality_name: string;
arr_type: string;
api_name: string;
created_at: Generated<string>;
}
export interface CustomFormatsTable {
id: Generated<number>;
name: string;
description: string | null;
include_in_rename: Generated<number>;
created_at: Generated<string>;
updated_at: Generated<string>;
}
// ============================================================================
// DEPENDENT ENTITY TABLES
// ============================================================================
export interface QualityProfilesTable {
id: Generated<number>;
name: string;
description: string | null;
upgrades_allowed: number;
minimum_custom_format_score: number;
upgrade_until_score: number;
upgrade_score_increment: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface QualityGroupsTable {
quality_profile_name: string;
name: string;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface CustomFormatConditionsTable {
custom_format_name: string;
name: string;
type: string;
arr_type: string;
negate: number;
required: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
// ============================================================================
// JUNCTION TABLES
// ============================================================================
export interface RegularExpressionTagsTable {
regular_expression_name: string;
tag_name: string;
}
export interface CustomFormatTagsTable {
custom_format_name: string;
tag_name: string;
}
export interface QualityProfileTagsTable {
quality_profile_name: string;
tag_name: string;
}
export interface QualityProfileLanguagesTable {
quality_profile_name: string;
language_name: string;
type: string;
}
export interface QualityGroupMembersTable {
quality_profile_name: string;
quality_group_name: string;
quality_name: string;
}
export interface QualityProfileQualitiesTable {
quality_profile_name: string;
quality_name: string | null;
quality_group_name: string | null;
position: number;
enabled: number;
upgrade_until: number;
}
export interface QualityProfileCustomFormatsTable {
quality_profile_name: string;
custom_format_name: string;
arr_type: string;
score: number;
}
// ============================================================================
// CUSTOM FORMAT CONDITION TYPE TABLES
// ============================================================================
export interface ConditionPatternsTable {
custom_format_name: string;
condition_name: string;
regular_expression_name: string;
}
export interface ConditionLanguagesTable {
custom_format_name: string;
condition_name: string;
language_name: string;
except_language: number;
}
export interface ConditionIndexerFlagsTable {
custom_format_name: string;
condition_name: string;
flag: string;
}
export interface ConditionSourcesTable {
custom_format_name: string;
condition_name: string;
source: string;
}
export interface ConditionResolutionsTable {
custom_format_name: string;
condition_name: string;
resolution: string;
}
export interface ConditionQualityModifiersTable {
custom_format_name: string;
condition_name: string;
quality_modifier: string;
}
export interface ConditionSizesTable {
custom_format_name: string;
condition_name: string;
min_bytes: number | null;
max_bytes: number | null;
}
export interface ConditionReleaseTypesTable {
custom_format_name: string;
condition_name: string;
release_type: string;
}
export interface ConditionYearsTable {
custom_format_name: string;
condition_name: string;
min_year: number | null;
max_year: number | null;
}
// ============================================================================
// CUSTOM FORMAT TESTING
// ============================================================================
export interface CustomFormatTestsTable {
custom_format_name: string;
title: string;
type: string;
should_match: number;
description: string | null;
created_at: Generated<string>;
}
// ============================================================================
// QUALITY PROFILE TESTING
// ============================================================================
export interface TestEntitiesTable {
id: Generated<number>;
type: 'movie' | 'series';
tmdb_id: number;
title: string;
year: number | null;
poster_path: string | null;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface TestReleasesTable {
id: Generated<number>;
entity_type: 'movie' | 'series';
entity_tmdb_id: number;
title: string;
size_bytes: number | null;
languages: string; // JSON array
indexers: string; // JSON array
flags: string; // JSON array
created_at: Generated<string>;
updated_at: Generated<string>;
}
// ============================================================================
// DELAY PROFILES
// ============================================================================
export interface DelayProfilesTable {
id: Generated<number>;
name: string;
preferred_protocol: string;
usenet_delay: number | null;
torrent_delay: number | null;
bypass_if_highest_quality: number;
bypass_if_above_custom_format_score: number;
minimum_custom_format_score: number | null;
created_at: Generated<string>;
updated_at: Generated<string>;
}
// ============================================================================
// MEDIA MANAGEMENT TABLES
// ============================================================================
export interface RadarrQualityDefinitionsTable {
name: string;
quality_name: string;
min_size: number;
max_size: number;
preferred_size: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface SonarrQualityDefinitionsTable {
name: string;
quality_name: string;
min_size: number;
max_size: number;
preferred_size: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface RadarrNamingTable {
name: string;
rename: number;
movie_format: string;
movie_folder_format: string;
replace_illegal_characters: number;
colon_replacement_format: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface SonarrNamingTable {
name: string;
rename: number;
standard_episode_format: string;
daily_episode_format: string;
anime_episode_format: string;
series_folder_format: string;
season_folder_format: string;
replace_illegal_characters: number;
colon_replacement_format: number;
custom_colon_replacement_format: string | null;
multi_episode_style: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface RadarrMediaSettingsTable {
name: string;
propers_repacks: string;
enable_media_info: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
export interface SonarrMediaSettingsTable {
name: string;
propers_repacks: string;
enable_media_info: number;
created_at: Generated<string>;
updated_at: Generated<string>;
}
// ============================================================================
// DATABASE INTERFACE
// ============================================================================
export interface PCDDatabase {
tags: TagsTable;
languages: LanguagesTable;
regular_expressions: RegularExpressionsTable;
qualities: QualitiesTable;
custom_formats: CustomFormatsTable;
quality_profiles: QualityProfilesTable;
quality_groups: QualityGroupsTable;
custom_format_conditions: CustomFormatConditionsTable;
regular_expression_tags: RegularExpressionTagsTable;
custom_format_tags: CustomFormatTagsTable;
quality_profile_tags: QualityProfileTagsTable;
quality_profile_languages: QualityProfileLanguagesTable;
quality_group_members: QualityGroupMembersTable;
quality_profile_qualities: QualityProfileQualitiesTable;
quality_profile_custom_formats: QualityProfileCustomFormatsTable;
condition_patterns: ConditionPatternsTable;
condition_languages: ConditionLanguagesTable;
condition_indexer_flags: ConditionIndexerFlagsTable;
condition_sources: ConditionSourcesTable;
condition_resolutions: ConditionResolutionsTable;
condition_quality_modifiers: ConditionQualityModifiersTable;
condition_sizes: ConditionSizesTable;
condition_release_types: ConditionReleaseTypesTable;
condition_years: ConditionYearsTable;
custom_format_tests: CustomFormatTestsTable;
test_entities: TestEntitiesTable;
test_releases: TestReleasesTable;
delay_profiles: DelayProfilesTable;
quality_api_mappings: QualityApiMappingsTable;
radarr_quality_definitions: RadarrQualityDefinitionsTable;
sonarr_quality_definitions: SonarrQualityDefinitionsTable;
radarr_naming: RadarrNamingTable;
sonarr_naming: SonarrNamingTable;
radarr_media_settings: RadarrMediaSettingsTable;
sonarr_media_settings: SonarrMediaSettingsTable;
}

View File

@@ -1,276 +0,0 @@
/**
* Type definitions for PCD (Profilarr Compliant Database) entities
* Based on PCD Schema v1
*/
// ============================================================================
// CORE ENTITY TYPES
// ============================================================================
export interface Tag {
name: string;
created_at: string;
}
export interface Language {
id: number;
name: string;
created_at: string;
updated_at: string;
}
export interface RegularExpression {
id: number;
name: string;
pattern: string;
regex101_id: string | null;
description: string | null;
created_at: string;
updated_at: string;
tags?: Tag[];
}
export interface Quality {
id: number;
name: string;
created_at: string;
updated_at: string;
}
export interface CustomFormat {
id: number;
name: string;
description: string | null;
created_at: string;
updated_at: string;
tags?: Tag[];
conditions?: CustomFormatCondition[];
}
// ============================================================================
// QUALITY PROFILE TYPES
// ============================================================================
export interface QualityProfile {
id: number;
name: string;
description: string | null;
upgrades_allowed: number; // 0 or 1 (boolean)
minimum_custom_format_score: number;
upgrade_until_score: number;
upgrade_score_increment: number;
created_at: string;
updated_at: string;
tags?: Tag[];
languages?: QualityProfileLanguage[];
qualities?: QualityProfileQuality[];
customFormats?: QualityProfileCustomFormat[];
}
export interface QualityGroup {
quality_profile_name: string;
name: string;
created_at: string;
updated_at: string;
members?: Quality[]; // Qualities in this group
}
export interface QualityProfileLanguage {
language: Language;
type: 'must' | 'only' | 'not' | 'simple';
}
export interface QualityProfileQuality {
quality_profile_name: string;
quality_name: string | null;
quality_group_name: string | null;
position: number;
enabled: number; // 0 or 1 (boolean)
upgrade_until: number; // 0 or 1 (boolean)
// Populated fields
quality?: Quality;
qualityGroup?: QualityGroup;
}
export interface QualityProfileCustomFormat {
customFormat: CustomFormat;
arr_type: PcdArrTarget;
score: number;
}
// ============================================================================
// CUSTOM FORMAT CONDITION TYPES
// ============================================================================
/**
* PCD arr targeting - includes 'all' to indicate a condition/score applies to all arr types
* This is different from $arr/types.ts ArrType which represents actual arr application types
*/
export type PcdArrTarget = 'radarr' | 'sonarr' | 'all';
export type ConditionType =
| 'release_title'
| 'release_group'
| 'edition'
| 'language'
| 'indexer_flag'
| 'source'
| 'resolution'
| 'quality_modifier'
| 'size'
| 'release_type'
| 'year';
export interface CustomFormatCondition {
custom_format_name: string;
name: string;
type: ConditionType;
arr_type: PcdArrTarget;
negate: number; // 0 or 1 (boolean)
required: number; // 0 or 1 (boolean)
created_at: string;
updated_at: string;
// Type-specific data (only one will be populated based on type)
patternData?: ConditionPattern;
languageData?: ConditionLanguage;
indexerFlagData?: ConditionIndexerFlag;
sourceData?: ConditionSource;
resolutionData?: ConditionResolution;
qualityModifierData?: ConditionQualityModifier;
sizeData?: ConditionSize;
releaseTypeData?: ConditionReleaseType;
yearData?: ConditionYear;
}
// Condition type-specific data structures
export interface ConditionPattern {
regular_expression_name: string;
regularExpression?: RegularExpression;
}
export interface ConditionLanguage {
language_name: string;
except_language: number; // 0 or 1 (boolean)
language?: Language;
}
export interface ConditionIndexerFlag {
flag: string;
}
export interface ConditionSource {
source: string;
}
export interface ConditionResolution {
resolution: string;
}
export interface ConditionQualityModifier {
quality_modifier: string;
}
export interface ConditionSize {
min_bytes: number | null;
max_bytes: number | null;
}
export interface ConditionReleaseType {
release_type: string;
}
export interface ConditionYear {
min_year: number | null;
max_year: number | null;
}
// ============================================================================
// RAW DATABASE ROW TYPES (for direct SQL queries)
// ============================================================================
export interface QualityProfileRow {
id: number;
name: string;
description: string | null;
upgrades_allowed: number;
minimum_custom_format_score: number;
upgrade_until_score: number;
upgrade_score_increment: number;
created_at: string;
updated_at: string;
}
export interface CustomFormatRow {
id: number;
name: string;
description: string | null;
created_at: string;
updated_at: string;
}
export interface CustomFormatConditionRow {
custom_format_name: string;
name: string;
type: string;
arr_type: string;
negate: number;
required: number;
created_at: string;
updated_at: string;
}
export interface QualityProfileCustomFormatRow {
quality_profile_name: string;
custom_format_name: string;
arr_type: string;
score: number;
}
export interface QualityProfileLanguageRow {
quality_profile_name: string;
language_name: string;
type: string;
}
export interface QualityProfileQualityRow {
quality_profile_name: string;
quality_name: string | null;
quality_group_name: string | null;
position: number;
enabled: number;
upgrade_until: number;
}
export interface QualityGroupRow {
quality_profile_name: string;
name: string;
created_at: string;
updated_at: string;
}
export interface QualityGroupMemberRow {
quality_profile_name: string;
quality_group_name: string;
quality_name: string;
}
// ============================================================================
// QUALITY PROFILE SCORING TYPES
// ============================================================================
export interface CustomFormatScoring {
name: string; // custom format name
tags: string[]; // tag names for filtering
scores: Record<string, number | null>; // arr_type -> score mapping
}
export interface QualityProfileScoring {
databaseId: number; // PCD database ID (for linking)
arrTypes: string[]; // Display arr types: ['radarr', 'sonarr']. Note: 'all' scores are applied to each type
customFormats: CustomFormatScoring[]; // All custom formats with their scores
minimum_custom_format_score: number; // Minimum score to accept
upgrade_until_score: number; // Stop upgrading when reached
upgrade_score_increment: number; // Minimum score improvement needed
}