mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-29 22:10:52 +01:00
feat(pcd): enhance generator with type overrides for semantic enums (media management)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
import { Database } from '@jsr/db__sqlite';
|
||||
import { columnTypeOverrides } from './pcd-type-overrides.ts';
|
||||
|
||||
// ============================================================================
|
||||
// CONFIGURATION
|
||||
@@ -257,26 +258,34 @@ function sqliteTypeToTs(sqliteType: string, nullable: boolean): string {
|
||||
|
||||
/**
|
||||
* Get the semantic TypeScript type for a column
|
||||
* Uses CHECK constraints for union types and naming patterns for booleans
|
||||
* Priority: 1) Manual overrides, 2) CHECK constraints, 3) Boolean patterns, 4) SQLite type
|
||||
*/
|
||||
function getSemanticType(
|
||||
tableName: string,
|
||||
column: ColumnInfo,
|
||||
checkConstraints: CheckConstraint[],
|
||||
nullable: boolean
|
||||
): string {
|
||||
// Check if this column has a CHECK IN constraint (union type)
|
||||
// 1. Check for manual type override (for columns that store numbers but need string types)
|
||||
const overrideKey = `${tableName}.${column.name}`;
|
||||
const override = columnTypeOverrides[overrideKey];
|
||||
if (override) {
|
||||
return nullable ? `(${override}) | null` : override;
|
||||
}
|
||||
|
||||
// 2. Check if this column has a CHECK IN constraint (union type)
|
||||
const constraint = checkConstraints.find((c) => c.column === column.name);
|
||||
if (constraint && constraint.values.length > 0) {
|
||||
const unionType = constraint.values.map((v) => `'${v}'`).join(' | ');
|
||||
return nullable ? `(${unionType}) | null` : unionType;
|
||||
}
|
||||
|
||||
// Check if this is a boolean column based on naming patterns
|
||||
// 3. Check if this is a boolean column based on naming patterns
|
||||
if (isBooleanColumn(column.name, column.type)) {
|
||||
return nullable ? 'boolean | null' : 'boolean';
|
||||
}
|
||||
|
||||
// Fall back to standard SQLite type mapping
|
||||
// 4. Fall back to standard SQLite type mapping
|
||||
return sqliteTypeToTs(column.type, nullable);
|
||||
}
|
||||
|
||||
@@ -378,7 +387,7 @@ function generateRowType(table: TableInfo): string {
|
||||
|
||||
for (const column of table.columns) {
|
||||
const nullable = isNullable(column);
|
||||
const tsType = getSemanticType(column, table.checkConstraints, nullable);
|
||||
const tsType = getSemanticType(table.name, column, table.checkConstraints, nullable);
|
||||
lines.push(`\t${column.name}: ${tsType};`);
|
||||
}
|
||||
|
||||
|
||||
59
scripts/pcd-type-overrides.ts
Normal file
59
scripts/pcd-type-overrides.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* PCD Type Overrides
|
||||
*
|
||||
* Manual type overrides for columns that store numeric values in the DB
|
||||
* but need semantic string types (because that's what the API expects).
|
||||
*
|
||||
* Format: 'table_name.column_name': 'TypeScript type'
|
||||
*
|
||||
* Note: Columns with CHECK constraints in the schema don't need overrides -
|
||||
* the generator parses those automatically.
|
||||
*/
|
||||
|
||||
export const columnTypeOverrides: Record<string, string> = {
|
||||
// Sonarr stores these as integers (0-5) but API expects semantic strings
|
||||
'sonarr_naming.colon_replacement_format':
|
||||
"'delete' | 'dash' | 'spaceDash' | 'spaceDashSpace' | 'smart' | 'custom'",
|
||||
'sonarr_naming.multi_episode_style':
|
||||
"'extend' | 'duplicate' | 'repeat' | 'scene' | 'range' | 'prefixedRange'"
|
||||
};
|
||||
|
||||
/**
|
||||
* DB value mappings for converting between numeric DB values and semantic strings.
|
||||
* Used by query read/write functions.
|
||||
*/
|
||||
export const colonReplacementFromDb: Record<number, string> = {
|
||||
0: 'delete',
|
||||
1: 'dash',
|
||||
2: 'spaceDash',
|
||||
3: 'spaceDashSpace',
|
||||
4: 'smart',
|
||||
5: 'custom'
|
||||
};
|
||||
|
||||
export const colonReplacementToDb: Record<string, number> = {
|
||||
delete: 0,
|
||||
dash: 1,
|
||||
spaceDash: 2,
|
||||
spaceDashSpace: 3,
|
||||
smart: 4,
|
||||
custom: 5
|
||||
};
|
||||
|
||||
export const multiEpisodeStyleFromDb: Record<number, string> = {
|
||||
0: 'extend',
|
||||
1: 'duplicate',
|
||||
2: 'repeat',
|
||||
3: 'scene',
|
||||
4: 'range',
|
||||
5: 'prefixedRange'
|
||||
};
|
||||
|
||||
export const multiEpisodeStyleToDb: Record<string, number> = {
|
||||
extend: 0,
|
||||
duplicate: 1,
|
||||
repeat: 2,
|
||||
scene: 3,
|
||||
range: 4,
|
||||
prefixedRange: 5
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
* AUTO-GENERATED - DO NOT EDIT MANUALLY
|
||||
*
|
||||
* Generated from: https://github.com/Dictionarry-Hub/schema/blob/local/ops/0.schema.sql
|
||||
* Generated at: 2026-01-27T11:52:25.907Z
|
||||
* Generated at: 2026-01-27T12:38:46.562Z
|
||||
*
|
||||
* To regenerate: deno task generate:pcd-types --version=local
|
||||
*/
|
||||
@@ -579,7 +579,7 @@ export interface RadarrNamingRow {
|
||||
movie_format: string;
|
||||
movie_folder_format: string;
|
||||
replace_illegal_characters: boolean;
|
||||
colon_replacement_format: string;
|
||||
colon_replacement_format: 'delete' | 'dash' | 'spaceDash' | 'spaceDashSpace' | 'smart';
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
@@ -593,16 +593,16 @@ export interface SonarrNamingRow {
|
||||
series_folder_format: string;
|
||||
season_folder_format: string;
|
||||
replace_illegal_characters: boolean;
|
||||
colon_replacement_format: number;
|
||||
colon_replacement_format: 'delete' | 'dash' | 'spaceDash' | 'spaceDashSpace' | 'smart' | 'custom';
|
||||
custom_colon_replacement_format: string | null;
|
||||
multi_episode_style: number;
|
||||
multi_episode_style: 'extend' | 'duplicate' | 'repeat' | 'scene' | 'range' | 'prefixedRange';
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface RadarrMediaSettingsRow {
|
||||
name: string | null;
|
||||
propers_repacks: string;
|
||||
propers_repacks: 'doNotPrefer' | 'preferAndUpgrade' | 'doNotUpgradeAutomatically';
|
||||
enable_media_info: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
@@ -610,7 +610,7 @@ export interface RadarrMediaSettingsRow {
|
||||
|
||||
export interface SonarrMediaSettingsRow {
|
||||
name: string | null;
|
||||
propers_repacks: string;
|
||||
propers_repacks: 'doNotPrefer' | 'preferAndUpgrade' | 'doNotUpgradeAutomatically';
|
||||
enable_media_info: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
|
||||
Reference in New Issue
Block a user