From 7fe06dcdb1ef13c01b75edac69b56a7fb57cfeb5 Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Wed, 28 Jan 2026 02:55:57 +1030 Subject: [PATCH] refactor(pcd): better file structure, remove watcher utils, update deps using tags instead of branches --- src/hooks.server.ts | 2 +- src/lib/server/jobs/logic/syncDatabases.ts | 2 +- src/lib/server/pcd/cache.ts | 561 ------------------ src/lib/server/pcd/core/errors.ts | 77 +++ .../server/pcd/{pcd.ts => core/manager.ts} | 46 +- src/lib/server/pcd/core/types.ts | 127 ++++ src/lib/server/pcd/database/cache.ts | 281 +++++++++ src/lib/server/pcd/database/compiler.ts | 53 ++ src/lib/server/pcd/database/registry.ts | 56 ++ src/lib/server/pcd/deps.ts | 167 ------ .../entities/customFormats/conditions/read.ts | 2 +- .../customFormats/conditions/update.ts | 4 +- .../pcd/entities/customFormats/create.ts | 4 +- .../pcd/entities/customFormats/delete.ts | 4 +- .../entities/customFormats/general/read.ts | 2 +- .../entities/customFormats/general/update.ts | 4 +- .../server/pcd/entities/customFormats/list.ts | 2 +- .../entities/customFormats/tests/create.ts | 2 +- .../entities/customFormats/tests/delete.ts | 2 +- .../pcd/entities/customFormats/tests/read.ts | 2 +- .../entities/customFormats/tests/update.ts | 2 +- .../pcd/entities/delayProfiles/create.ts | 4 +- .../pcd/entities/delayProfiles/delete.ts | 4 +- .../server/pcd/entities/delayProfiles/read.ts | 2 +- .../pcd/entities/delayProfiles/update.ts | 4 +- .../mediaManagement/media-settings/create.ts | 4 +- .../mediaManagement/media-settings/delete.ts | 4 +- .../mediaManagement/media-settings/read.ts | 2 +- .../mediaManagement/media-settings/update.ts | 4 +- .../entities/mediaManagement/naming/create.ts | 4 +- .../entities/mediaManagement/naming/delete.ts | 4 +- .../entities/mediaManagement/naming/read.ts | 2 +- .../entities/mediaManagement/naming/update.ts | 4 +- .../quality-definitions/create.ts | 4 +- .../quality-definitions/delete.ts | 4 +- .../quality-definitions/read.ts | 2 +- .../quality-definitions/update.ts | 4 +- .../pcd/entities/qualityProfiles/create.ts | 4 +- .../pcd/entities/qualityProfiles/delete.ts | 4 +- .../qualityProfiles/entityTests/create.ts | 4 +- .../qualityProfiles/entityTests/delete.ts | 4 +- .../qualityProfiles/entityTests/read.ts | 2 +- .../entityTests/releases/create.ts | 4 +- .../entityTests/releases/delete.ts | 4 +- .../entityTests/releases/update.ts | 4 +- .../entities/qualityProfiles/general/read.ts | 2 +- .../qualityProfiles/general/update.ts | 4 +- .../pcd/entities/qualityProfiles/list.ts | 2 +- .../qualityProfiles/qualities/read.ts | 2 +- .../qualityProfiles/qualities/update.ts | 4 +- .../entities/qualityProfiles/scoring/read.ts | 2 +- .../qualityProfiles/scoring/update.ts | 4 +- .../pcd/entities/regularExpressions/create.ts | 4 +- .../pcd/entities/regularExpressions/delete.ts | 4 +- .../pcd/entities/regularExpressions/read.ts | 2 +- .../pcd/entities/regularExpressions/update.ts | 4 +- src/lib/server/pcd/git/dependencies.ts | 235 ++++++++ src/lib/server/pcd/index.ts | 75 +++ src/lib/server/pcd/{ => manifest}/manifest.ts | 37 +- .../pcd/{ops.ts => operations/loader.ts} | 51 +- src/lib/server/pcd/operations/sql.ts | 64 ++ src/lib/server/pcd/{ => operations}/writer.ts | 108 +--- src/lib/server/pcd/paths.ts | 19 - src/lib/server/pcd/readme.ts | 28 - .../server/sync/customFormats/transformer.ts | 2 +- src/lib/server/sync/delayProfiles/syncer.ts | 2 +- src/lib/server/sync/mediaManagement/syncer.ts | 2 +- src/lib/server/sync/qualityProfiles/syncer.ts | 2 +- .../sync/qualityProfiles/transformer.ts | 2 +- src/lib/server/utils/git/Git.ts | 1 + src/lib/server/utils/git/repo.ts | 7 + src/routes/api/arr/[id]/library/+server.ts | 2 +- src/routes/api/databases/+server.ts | 2 +- .../api/v1/entity-testing/evaluate/+server.ts | 2 +- src/routes/api/v1/health/+server.ts | 2 +- src/routes/arr/[id]/sync/+page.server.ts | 2 +- src/routes/custom-formats/+page.server.ts | 2 +- .../[databaseId]/+page.server.ts | 2 +- .../[id]/conditions/+page.server.ts | 6 +- .../[databaseId]/[id]/general/+page.server.ts | 6 +- .../[databaseId]/[id]/testing/+page.server.ts | 4 +- .../[id]/testing/[testId]/+page.server.ts | 4 +- .../[id]/testing/new/+page.server.ts | 4 +- .../[databaseId]/new/+page.server.ts | 6 +- src/routes/databases/+page.server.ts | 2 +- .../databases/[id]/changes/+page.server.ts | 6 +- .../databases/[id]/config/+page.server.ts | 5 +- .../databases/[id]/settings/+page.server.ts | 2 +- src/routes/databases/new/+page.server.ts | 2 +- src/routes/delay-profiles/+page.server.ts | 2 +- .../[databaseId]/+page.server.ts | 2 +- .../[databaseId]/[id]/+page.server.ts | 6 +- .../[databaseId]/new/+page.server.ts | 6 +- src/routes/media-management/+page.server.ts | 2 +- .../[databaseId]/+layout.server.ts | 4 +- .../media-settings/+page.server.ts | 2 +- .../media-settings/new/+page.server.ts | 6 +- .../radarr/[name]/+page.server.ts | 6 +- .../sonarr/[name]/+page.server.ts | 6 +- .../[databaseId]/naming/+page.server.ts | 2 +- .../[databaseId]/naming/new/+page.server.ts | 6 +- .../naming/radarr/[name]/+page.server.ts | 6 +- .../naming/sonarr/[name]/+page.server.ts | 6 +- .../quality-definitions/+page.server.ts | 2 +- .../quality-definitions/new/+page.server.ts | 6 +- .../radarr/[name]/+page.server.ts | 6 +- .../sonarr/[name]/+page.server.ts | 6 +- src/routes/quality-profiles/+page.server.ts | 2 +- .../[databaseId]/+page.server.ts | 2 +- .../[databaseId]/[id]/general/+page.server.ts | 6 +- .../[id]/qualities/+page.server.ts | 6 +- .../[databaseId]/[id]/scoring/+page.server.ts | 6 +- .../[databaseId]/new/+page.server.ts | 6 +- .../entity-testing/+page.server.ts | 2 +- .../[databaseId]/+page.server.ts | 4 +- .../regular-expressions/+page.server.ts | 2 +- .../[databaseId]/+page.server.ts | 2 +- .../[databaseId]/[id]/+page.server.ts | 6 +- .../[databaseId]/new/+page.server.ts | 6 +- 119 files changed, 1244 insertions(+), 1106 deletions(-) delete mode 100644 src/lib/server/pcd/cache.ts create mode 100644 src/lib/server/pcd/core/errors.ts rename src/lib/server/pcd/{pcd.ts => core/manager.ts} (90%) create mode 100644 src/lib/server/pcd/core/types.ts create mode 100644 src/lib/server/pcd/database/cache.ts create mode 100644 src/lib/server/pcd/database/compiler.ts create mode 100644 src/lib/server/pcd/database/registry.ts delete mode 100644 src/lib/server/pcd/deps.ts create mode 100644 src/lib/server/pcd/git/dependencies.ts create mode 100644 src/lib/server/pcd/index.ts rename src/lib/server/pcd/{ => manifest}/manifest.ts (85%) rename src/lib/server/pcd/{ops.ts => operations/loader.ts} (87%) create mode 100644 src/lib/server/pcd/operations/sql.ts rename src/lib/server/pcd/{ => operations}/writer.ts (75%) delete mode 100644 src/lib/server/pcd/paths.ts delete mode 100644 src/lib/server/pcd/readme.ts diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 2e32c56..ed0cb66 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -8,7 +8,7 @@ import { db } from '$db/db.ts'; import { runMigrations } from '$db/migrations.ts'; import { initializeJobs } from '$jobs/init.ts'; import { jobScheduler } from '$jobs/scheduler.ts'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { getAuthState, isPublicPath, diff --git a/src/lib/server/jobs/logic/syncDatabases.ts b/src/lib/server/jobs/logic/syncDatabases.ts index 8aef7b0..5af981f 100644 --- a/src/lib/server/jobs/logic/syncDatabases.ts +++ b/src/lib/server/jobs/logic/syncDatabases.ts @@ -3,7 +3,7 @@ * Checks for databases that need syncing and pulls updates if auto_pull is enabled */ -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; diff --git a/src/lib/server/pcd/cache.ts b/src/lib/server/pcd/cache.ts deleted file mode 100644 index 7d688c8..0000000 --- a/src/lib/server/pcd/cache.ts +++ /dev/null @@ -1,561 +0,0 @@ -/** - * PCD Cache - In-memory compiled view of PCD operations - */ - -import { Database } from '@jsr/db__sqlite'; -import { Kysely } from 'kysely'; -// @ts-ignore - Deno JSR import not recognized by svelte-check -import { DenoSqlite3Dialect } from '@soapbox/kysely-deno-sqlite'; -import { logger } from '$logger/logger.ts'; -import { loadAllOperations, validateOperations } from './ops.ts'; -import { - disableDatabaseInstance, - databaseInstancesQueries -} from '$db/queries/databaseInstances.ts'; -import type { PCDDatabase } from '$shared/pcd/types.ts'; -import { triggerSyncs } from '$sync/processor.ts'; - -/** - * Stats returned from cache build - */ -export interface CacheBuildStats { - schema: number; - base: number; - tweaks: number; - user: number; - timing: number; -} - -/** - * PCDCache - Manages an in-memory compiled database for a single PCD - */ -export class PCDCache { - private db: Database | null = null; - private kysely: Kysely | null = null; - private pcdPath: string; - private databaseInstanceId: number; - private built = false; - - constructor(pcdPath: string, databaseInstanceId: number) { - this.pcdPath = pcdPath; - this.databaseInstanceId = databaseInstanceId; - } - - /** - * Build the cache by executing all operations in layer order - * Returns stats about what was loaded - */ - async build(): Promise { - const startTime = performance.now(); - - try { - // 1. Create in-memory database - // Enable int64 mode to properly handle large integers (e.g., file sizes in bytes) - this.db = new Database(':memory:', { int64: true }); - - // Enable foreign keys - this.db.exec('PRAGMA foreign_keys = ON'); - - // Initialize Kysely query builder - this.kysely = new Kysely({ - dialect: new DenoSqlite3Dialect({ - database: this.db - }) - }); - - // 2. Register helper functions - this.registerHelperFunctions(); - - // 3. Load all operations - const operations = await loadAllOperations(this.pcdPath); - validateOperations(operations); - - // Count ops per layer - const stats: CacheBuildStats = { - schema: operations.filter((o) => o.layer === 'schema').length, - base: operations.filter((o) => o.layer === 'base').length, - tweaks: operations.filter((o) => o.layer === 'tweaks').length, - user: operations.filter((o) => o.layer === 'user').length, - timing: 0 - }; - - // 4. Execute operations in order - for (const operation of operations) { - try { - this.db.exec(operation.sql); - } catch (error) { - throw new Error( - `Failed to execute operation ${operation.filename} in ${operation.layer} layer: ${error}` - ); - } - } - - this.built = true; - stats.timing = Math.round(performance.now() - startTime); - - return stats; - } catch (error) { - await logger.error('Failed to build PCD cache', { - source: 'PCDCache', - meta: { error: String(error), databaseInstanceId: this.databaseInstanceId } - }); - - // Disable the database instance - await disableDatabaseInstance(this.databaseInstanceId); - - // Clean up - this.close(); - throw error; - } - } - - /** - * Register SQL helper functions (qp, cf, dp, tag) - */ - private registerHelperFunctions(): void { - if (!this.db) return; - - // qp(name) - Quality profile lookup by name - this.db.function('qp', (name: string) => { - const result = this.db!.prepare('SELECT id FROM quality_profiles WHERE name = ?').get( - name - ) as { id: number } | undefined; - if (!result) { - throw new Error(`Quality profile not found: ${name}`); - } - return result.id; - }); - - // cf(name) - Custom format lookup by name - this.db.function('cf', (name: string) => { - const result = this.db!.prepare('SELECT id FROM custom_formats WHERE name = ?').get(name) as - | { id: number } - | undefined; - if (!result) { - throw new Error(`Custom format not found: ${name}`); - } - return result.id; - }); - - // dp(name) - Delay profile lookup by name - this.db.function('dp', (name: string) => { - const result = this.db!.prepare('SELECT id FROM delay_profiles WHERE name = ?').get(name) as - | { id: number } - | undefined; - if (!result) { - throw new Error(`Delay profile not found: ${name}`); - } - return result.id; - }); - - // tag(name) - Tag lookup by name (creates if not exists) - this.db.function('tag', (name: string) => { - const result = this.db!.prepare('SELECT id FROM tags WHERE name = ?').get(name) as - | { id: number } - | undefined; - if (!result) { - throw new Error(`Tag not found: ${name}`); - } - return result.id; - }); - } - - /** - * Check if cache is built and ready - */ - isBuilt(): boolean { - return this.built && this.db !== null; - } - - /** - * Close the database connection - */ - close(): void { - if (this.kysely) { - this.kysely.destroy(); - this.kysely = null; - } - if (this.db) { - this.db.close(); - this.db = null; - } - this.built = false; - } - - /** - * Get the Kysely query builder - * Use this for type-safe queries - */ - get kb(): Kysely { - if (!this.kysely) { - throw new Error('Cache not built'); - } - return this.kysely; - } - - // ============================================================================ - // QUERY API - // ============================================================================ - - /** - * Execute a raw SQL query and return all rows - * Use this in your query functions in pcd/queries/*.ts - */ - query( - sql: string, - ...params: (string | number | null | boolean | Uint8Array)[] - ): T[] { - if (!this.isBuilt()) { - throw new Error('Cache not built'); - } - - return this.db!.prepare(sql).all(...params) as T[]; - } - - /** - * Execute a raw SQL query and return a single row - * Use this in your query functions in pcd/queries/*.ts - */ - queryOne( - sql: string, - ...params: (string | number | null | boolean | Uint8Array)[] - ): T | undefined { - if (!this.isBuilt()) { - throw new Error('Cache not built'); - } - - return this.db!.prepare(sql).get(...params) as T | undefined; - } - - /** - * Validate SQL statements by doing a dry-run in a transaction - * Returns null if valid, or an error message if invalid - * - * This is a safety check before writing operations to files. - * It catches FK violations, constraint errors, etc. - */ - validateSql(sqlStatements: string[]): { valid: boolean; error?: string } { - if (!this.isBuilt()) { - return { valid: false, error: 'Cache not built' }; - } - - try { - // Start a savepoint (nested transaction) - this.db!.exec('SAVEPOINT validation_check'); - - try { - // Try to execute each statement - for (const sql of sqlStatements) { - this.db!.exec(sql); - } - - // All statements executed successfully - return { valid: true }; - } finally { - // Always rollback - this is just a validation check - this.db!.exec('ROLLBACK TO SAVEPOINT validation_check'); - this.db!.exec('RELEASE SAVEPOINT validation_check'); - } - } catch (error) { - // Parse the error to provide a helpful message - const errorStr = String(error); - - // Common SQLite constraint errors - if (errorStr.includes('FOREIGN KEY constraint failed')) { - return { - valid: false, - error: `Foreign key constraint failed - referenced entity does not exist. ${errorStr}` - }; - } - if (errorStr.includes('UNIQUE constraint failed')) { - return { - valid: false, - error: `Unique constraint failed - duplicate entry. ${errorStr}` - }; - } - if (errorStr.includes('NOT NULL constraint failed')) { - return { - valid: false, - error: `Required field is missing. ${errorStr}` - }; - } - if (errorStr.includes('CHECK constraint failed')) { - return { - valid: false, - error: `Value validation failed. ${errorStr}` - }; - } - - return { - valid: false, - error: `Database validation failed: ${errorStr}` - }; - } - } -} - -// ============================================================================ -// MODULE-LEVEL REGISTRY AND FUNCTIONS -// ============================================================================ - -/** - * Cache registry - maps database instance ID to PCDCache - */ -const caches = new Map(); - -/** - * File watchers - maps database instance ID to watcher - */ -const watchers = new Map(); - -/** - * Debounce timers - maps "databaseInstanceId:pcdPath" to timer - */ -const debounceTimers = new Map(); - -/** - * Debounce delay in milliseconds - */ -const DEBOUNCE_DELAY = 500; - -/** - * Compile a PCD into an in-memory cache - * Returns build stats for logging - */ -export async function compile( - pcdPath: string, - databaseInstanceId: number -): Promise { - // Stop any existing watchers - stopWatch(databaseInstanceId); - - // Close existing cache if present - const existing = caches.get(databaseInstanceId); - if (existing) { - existing.close(); - } - - // Create and build new cache - const cache = new PCDCache(pcdPath, databaseInstanceId); - const stats = await cache.build(); - - // Store in registry - caches.set(databaseInstanceId, cache); - - return stats; -} - -/** - * Get a compiled cache by database instance ID - */ -export function getCache(databaseInstanceId: number): PCDCache | undefined { - return caches.get(databaseInstanceId); -} - -/** - * Get all currently cached database instance IDs (for debugging) - */ -export function getCachedDatabaseIds(): number[] { - return Array.from(caches.keys()); -} - -/** - * Invalidate a cache (close and remove from registry) - */ -export function invalidate(databaseInstanceId: number): void { - const cache = caches.get(databaseInstanceId); - if (cache) { - cache.close(); - caches.delete(databaseInstanceId); - } - - // Stop file watcher and debounce timers - stopWatch(databaseInstanceId); -} - -/** - * Invalidate all caches - */ -export function invalidateAll(): void { - const ids = Array.from(caches.keys()); - for (const id of ids) { - invalidate(id); - } -} - -// ============================================================================ -// FILE WATCHING -// ============================================================================ - -/** - * Start watching PCD directories for changes - */ -export async function startWatch(pcdPath: string, databaseInstanceId: number): Promise { - // Stop existing watcher if present - stopWatch(databaseInstanceId); - - const pathsToWatch: string[] = []; - - // Watch ops directory - const opsPath = `${pcdPath}/ops`; - try { - await Deno.stat(opsPath); - pathsToWatch.push(opsPath); - } catch { - // ops directory doesn't exist, skip - } - - // Watch deps/schema/ops directory - const schemaOpsPath = `${pcdPath}/deps/schema/ops`; - try { - await Deno.stat(schemaOpsPath); - pathsToWatch.push(schemaOpsPath); - } catch { - // schema ops directory doesn't exist, skip - } - - // Watch tweaks directory (optional) - const tweaksPath = `${pcdPath}/tweaks`; - try { - await Deno.stat(tweaksPath); - pathsToWatch.push(tweaksPath); - } catch { - // tweaks directory doesn't exist, that's ok - } - - // Watch user_ops directory (create if doesn't exist) - const userOpsPath = `${pcdPath}/user_ops`; - try { - await Deno.mkdir(userOpsPath, { recursive: true }); - } catch (error) { - if (!(error instanceof Deno.errors.AlreadyExists)) { - await logger.warn('Failed to create user_ops directory', { - source: 'PCDCache', - meta: { error: String(error), pcdPath } - }); - } - } - pathsToWatch.push(userOpsPath); - - if (pathsToWatch.length === 0) { - await logger.warn('No directories to watch for PCD', { - source: 'PCDCache', - meta: { pcdPath, databaseInstanceId } - }); - return; - } - - const watcher = Deno.watchFs(pathsToWatch); - watchers.set(databaseInstanceId, watcher); - - // Process file system events in the background - (async () => { - try { - for await (const event of watcher) { - // Only rebuild on modify, create, or remove events - if (['modify', 'create', 'remove'].includes(event.kind)) { - // Only care about .sql files - const hasSqlFile = event.paths.some((path) => path.endsWith('.sql')); - if (!hasSqlFile) continue; - - await logger.debug('File change detected, scheduling rebuild', { - source: 'PCDCache', - meta: { event: event.kind, paths: event.paths, databaseInstanceId } - }); - - // Debounce the rebuild - scheduleRebuild(pcdPath, databaseInstanceId); - } - } - } catch (error) { - // Watcher was closed or errored - if (error instanceof Deno.errors.BadResource) { - // This is expected when we close the watcher - return; - } - - await logger.error('File watcher error', { - source: 'PCDCache', - meta: { error: String(error), databaseInstanceId } - }); - } - })(); -} - -/** - * Stop watching a PCD for changes - */ -function stopWatch(databaseInstanceId: number, pcdPath?: string): void { - const watcher = watchers.get(databaseInstanceId); - if (watcher) { - watcher.close(); - watchers.delete(databaseInstanceId); - } - - // Clear any pending debounce timer for this specific path - if (pcdPath) { - const timerKey = `${databaseInstanceId}:${pcdPath}`; - const timer = debounceTimers.get(timerKey); - if (timer) { - clearTimeout(timer); - debounceTimers.delete(timerKey); - } - } else { - // Clear all timers for this databaseInstanceId (fallback) - for (const [key, timer] of debounceTimers.entries()) { - if (key.startsWith(`${databaseInstanceId}:`)) { - clearTimeout(timer); - debounceTimers.delete(key); - } - } - } -} - -/** - * Schedule a rebuild with debouncing - */ -function scheduleRebuild(pcdPath: string, databaseInstanceId: number): void { - const timerKey = `${databaseInstanceId}:${pcdPath}`; - - // Clear existing timer for this specific path - const existingTimer = debounceTimers.get(timerKey); - if (existingTimer) { - clearTimeout(existingTimer); - } - - // Schedule new rebuild - const timer = setTimeout(async () => { - try { - const stats = await compile(pcdPath, databaseInstanceId); - // Restart watch after rebuild (compile clears watchers) - await startWatch(pcdPath, databaseInstanceId); - - // Get database name for logging - const instance = databaseInstancesQueries.getById(databaseInstanceId); - const name = instance?.name ?? `ID:${databaseInstanceId}`; - - await logger.debug(`Rebuild cache "${name}"`, { - source: 'PCDCache', - meta: { - schema: stats.schema, - base: stats.base, - tweaks: stats.tweaks, - user: stats.user, - timing: `${stats.timing}ms` - } - }); - - // Trigger arr syncs for configs with on_change trigger - await triggerSyncs({ event: 'on_change', databaseId: databaseInstanceId }); - } catch (error) { - await logger.error('Failed to rebuild cache', { - source: 'PCDCache', - meta: { error: String(error), databaseInstanceId, pcdPath } - }); - } - - debounceTimers.delete(timerKey); - }, DEBOUNCE_DELAY) as unknown as number; - - debounceTimers.set(timerKey, timer); -} diff --git a/src/lib/server/pcd/core/errors.ts b/src/lib/server/pcd/core/errors.ts new file mode 100644 index 0000000..b473076 --- /dev/null +++ b/src/lib/server/pcd/core/errors.ts @@ -0,0 +1,77 @@ +/** + * PCD Error Classes + * Custom error types for the PCD system + */ + +/** + * Base error class for PCD-related errors + */ +export class PCDError extends Error { + constructor(message: string) { + super(message); + this.name = 'PCDError'; + } +} + +/** + * Error during cache building + */ +export class CacheBuildError extends PCDError { + constructor( + message: string, + public readonly databaseInstanceId?: number + ) { + super(message); + this.name = 'CacheBuildError'; + } +} + +/** + * Error during operation execution + */ +export class OperationError extends PCDError { + constructor( + message: string, + public readonly operation?: string, + public readonly layer?: string + ) { + super(message); + this.name = 'OperationError'; + } +} + +/** + * Error during SQL validation + */ +export class ValidationError extends PCDError { + constructor( + message: string, + public readonly sql?: string[] + ) { + super(message); + this.name = 'ValidationError'; + } +} + +/** + * Error during dependency resolution + */ +export class DependencyError extends PCDError { + constructor( + message: string, + public readonly dependency?: string + ) { + super(message); + this.name = 'DependencyError'; + } +} + +/** + * Error during manifest validation + */ +export class ManifestValidationError extends PCDError { + constructor(message: string) { + super(message); + this.name = 'ManifestValidationError'; + } +} diff --git a/src/lib/server/pcd/pcd.ts b/src/lib/server/pcd/core/manager.ts similarity index 90% rename from src/lib/server/pcd/pcd.ts rename to src/lib/server/pcd/core/manager.ts index cb59cf9..2fd2bba 100644 --- a/src/lib/server/pcd/pcd.ts +++ b/src/lib/server/pcd/core/manager.ts @@ -5,27 +5,14 @@ import { Git, clone, type GitStatus, type UpdateInfo } from '$utils/git/index.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import type { DatabaseInstance } from '$db/queries/databaseInstances.ts'; -import { loadManifest, type Manifest } from './manifest.ts'; -import { getPCDPath } from './paths.ts'; -import { processDependencies, syncDependencies } from './deps.ts'; -import { compile, invalidate, startWatch, getCache } from './cache.ts'; +import { loadManifest, type Manifest } from '../manifest/manifest.ts'; +import { getPCDPath } from '../operations/loader.ts'; +import { processDependencies, syncDependencies, validateDependencies } from '../git/dependencies.ts'; +import { compile, invalidate } from '../database/compiler.ts'; +import { getCache } from '../database/registry.ts'; import { logger } from '$logger/logger.ts'; import { triggerSyncs } from '$sync/processor.ts'; - -export interface LinkOptions { - repositoryUrl: string; - name: string; - branch?: string; - syncStrategy?: number; - autoPull?: boolean; - personalAccessToken?: string; -} - -export interface SyncResult { - success: boolean; - commitsBehind: number; - error?: string; -} +import type { LinkOptions, SyncResult } from './types.ts'; /** * PCD Manager - Manages the lifecycle of Profilarr Compliant Databases @@ -81,11 +68,10 @@ class PCDManager { throw new Error('Failed to retrieve created database instance'); } - // Compile cache and start watching (only if enabled) + // Compile cache (only if enabled) if (instance.enabled) { try { const stats = await compile(localPath, id); - await startWatch(localPath, id); await logger.debug(`Cache compiled for "${options.name}"`, { source: 'PCDManager', @@ -175,11 +161,10 @@ class PCDManager { // Update last_synced_at databaseInstancesQueries.updateSyncedAt(id); - // Recompile cache and restart watching (only if enabled) + // Recompile cache (only if enabled) if (instance.enabled) { try { await compile(instance.local_path, id); - await startWatch(instance.local_path, id); } catch (error) { await logger.error('Failed to recompile PCD cache after sync', { source: 'PCDManager', @@ -290,6 +275,18 @@ class PCDManager { const instances = databaseInstancesQueries.getAll(); const enabledInstances = instances.filter((instance) => instance.enabled); + // Validate dependencies for all instances first + for (const instance of enabledInstances) { + try { + await validateDependencies(instance.local_path); + } catch (error) { + await logger.error(`Failed to validate dependencies for "${instance.name}"`, { + source: 'PCDManager', + meta: { error: String(error), databaseId: instance.id } + }); + } + } + // Collect results for aggregate logging const results: Array<{ name: string; @@ -300,11 +297,10 @@ class PCDManager { error?: string; }> = []; - // Compile and watch all enabled instances + // Compile all enabled instances for (const instance of enabledInstances) { try { const stats = await compile(instance.local_path, instance.id); - await startWatch(instance.local_path, instance.id); results.push({ name: instance.name, diff --git a/src/lib/server/pcd/core/types.ts b/src/lib/server/pcd/core/types.ts new file mode 100644 index 0000000..d1f1369 --- /dev/null +++ b/src/lib/server/pcd/core/types.ts @@ -0,0 +1,127 @@ +/** + * PCD Core Types + * Consolidated type definitions for the PCD system + */ + +import type { CompiledQuery } from 'kysely'; + +// ============================================================================ +// OPERATION TYPES +// ============================================================================ + +/** + * Which layer an operation belongs to + */ +export type OperationLayer = 'base' | 'user'; + +/** + * Type of operation being performed + */ +export type OperationType = 'create' | 'update' | 'delete'; + +/** + * Writable layers (excludes schema which is read-only) + */ +export type WritableLayer = 'base' | 'tweaks' | 'user'; + +/** + * A loaded SQL operation from disk + */ +export interface Operation { + filename: string; + filepath: string; + sql: string; + order: number; + layer: 'schema' | 'base' | 'tweaks' | 'user'; +} + +/** + * Metadata for an operation - used for optimization and tracking + */ +export interface OperationMetadata { + /** The type of operation */ + operation: OperationType; + /** The entity type (e.g., 'delay_profile', 'quality_profile') */ + entity: string; + /** The entity name (current name for create/update, name being deleted for delete) */ + name: string; + /** Previous name if this is a rename operation */ + previousName?: string; +} + +// ============================================================================ +// CACHE TYPES +// ============================================================================ + +/** + * Stats returned from cache build + */ +export interface CacheBuildStats { + schema: number; + base: number; + tweaks: number; + user: number; + timing: number; +} + +/** + * Result of SQL validation + */ +export interface ValidationResult { + valid: boolean; + error?: string; +} + +// ============================================================================ +// WRITER TYPES +// ============================================================================ + +/** + * Options for writing an operation + */ +export interface WriteOptions { + /** The database instance ID */ + databaseId: number; + /** Which layer to write to */ + layer: OperationLayer; + /** Description for the operation (used in filename) */ + description: string; + /** The compiled Kysely queries to write */ + queries: CompiledQuery[]; + /** Metadata for optimization and tracking */ + metadata?: OperationMetadata; +} + +/** + * Result of a write operation + */ +export interface WriteResult { + success: boolean; + filepath?: string; + error?: string; +} + +// ============================================================================ +// MANAGER TYPES +// ============================================================================ + +/** + * Options for linking a new PCD repository + */ +export interface LinkOptions { + repositoryUrl: string; + name: string; + branch?: string; + syncStrategy?: number; + autoPull?: boolean; + personalAccessToken?: string; +} + +/** + * Result of syncing a PCD repository + */ +export interface SyncResult { + success: boolean; + commitsBehind: number; + error?: string; +} diff --git a/src/lib/server/pcd/database/cache.ts b/src/lib/server/pcd/database/cache.ts new file mode 100644 index 0000000..baa7c3d --- /dev/null +++ b/src/lib/server/pcd/database/cache.ts @@ -0,0 +1,281 @@ +/** + * PCD Cache - In-memory compiled view of PCD operations + */ + +import { Database } from '@jsr/db__sqlite'; +import { Kysely } from 'kysely'; +// @ts-ignore - Deno JSR import not recognized by svelte-check +import { DenoSqlite3Dialect } from '@soapbox/kysely-deno-sqlite'; +import { logger } from '$logger/logger.ts'; +import { loadAllOperations, validateOperations } from '../operations/loader.ts'; +import { disableDatabaseInstance } from '$db/queries/databaseInstances.ts'; +import type { PCDDatabase } from '$shared/pcd/types.ts'; +import type { CacheBuildStats, ValidationResult } from '../core/types.ts'; + +/** + * PCDCache - Manages an in-memory compiled database for a single PCD + */ +export class PCDCache { + private db: Database | null = null; + private kysely: Kysely | null = null; + private pcdPath: string; + private databaseInstanceId: number; + private built = false; + + constructor(pcdPath: string, databaseInstanceId: number) { + this.pcdPath = pcdPath; + this.databaseInstanceId = databaseInstanceId; + } + + /** + * Build the cache by executing all operations in layer order + * Returns stats about what was loaded + */ + async build(): Promise { + const startTime = performance.now(); + + try { + // 1. Create in-memory database + // Enable int64 mode to properly handle large integers (e.g., file sizes in bytes) + this.db = new Database(':memory:', { int64: true }); + + // Enable foreign keys + this.db.exec('PRAGMA foreign_keys = ON'); + + // Initialize Kysely query builder + this.kysely = new Kysely({ + dialect: new DenoSqlite3Dialect({ + database: this.db + }) + }); + + // 2. Register helper functions + this.registerHelperFunctions(); + + // 3. Load all operations + const operations = await loadAllOperations(this.pcdPath); + validateOperations(operations); + + // Count ops per layer + const stats: CacheBuildStats = { + schema: operations.filter((o) => o.layer === 'schema').length, + base: operations.filter((o) => o.layer === 'base').length, + tweaks: operations.filter((o) => o.layer === 'tweaks').length, + user: operations.filter((o) => o.layer === 'user').length, + timing: 0 + }; + + // 4. Execute operations in order + for (const operation of operations) { + try { + this.db.exec(operation.sql); + } catch (error) { + throw new Error( + `Failed to execute operation ${operation.filename} in ${operation.layer} layer: ${error}` + ); + } + } + + this.built = true; + stats.timing = Math.round(performance.now() - startTime); + + return stats; + } catch (error) { + await logger.error('Failed to build PCD cache', { + source: 'PCDCache', + meta: { error: String(error), databaseInstanceId: this.databaseInstanceId } + }); + + // Disable the database instance + await disableDatabaseInstance(this.databaseInstanceId); + + // Clean up + this.close(); + throw error; + } + } + + /** + * Register SQL helper functions (qp, cf, dp, tag) + */ + private registerHelperFunctions(): void { + if (!this.db) return; + + // qp(name) - Quality profile lookup by name + this.db.function('qp', (name: string) => { + const result = this.db!.prepare('SELECT id FROM quality_profiles WHERE name = ?').get( + name + ) as { id: number } | undefined; + if (!result) { + throw new Error(`Quality profile not found: ${name}`); + } + return result.id; + }); + + // cf(name) - Custom format lookup by name + this.db.function('cf', (name: string) => { + const result = this.db!.prepare('SELECT id FROM custom_formats WHERE name = ?').get(name) as + | { id: number } + | undefined; + if (!result) { + throw new Error(`Custom format not found: ${name}`); + } + return result.id; + }); + + // dp(name) - Delay profile lookup by name + this.db.function('dp', (name: string) => { + const result = this.db!.prepare('SELECT id FROM delay_profiles WHERE name = ?').get(name) as + | { id: number } + | undefined; + if (!result) { + throw new Error(`Delay profile not found: ${name}`); + } + return result.id; + }); + + // tag(name) - Tag lookup by name (creates if not exists) + this.db.function('tag', (name: string) => { + const result = this.db!.prepare('SELECT id FROM tags WHERE name = ?').get(name) as + | { id: number } + | undefined; + if (!result) { + throw new Error(`Tag not found: ${name}`); + } + return result.id; + }); + } + + /** + * Check if cache is built and ready + */ + isBuilt(): boolean { + return this.built && this.db !== null; + } + + /** + * Close the database connection + */ + close(): void { + if (this.kysely) { + this.kysely.destroy(); + this.kysely = null; + } + if (this.db) { + this.db.close(); + this.db = null; + } + this.built = false; + } + + /** + * Get the Kysely query builder + * Use this for type-safe queries + */ + get kb(): Kysely { + if (!this.kysely) { + throw new Error('Cache not built'); + } + return this.kysely; + } + + // ============================================================================ + // QUERY API + // ============================================================================ + + /** + * Execute a raw SQL query and return all rows + * Use this in your query functions in pcd/queries/*.ts + */ + query( + sql: string, + ...params: (string | number | null | boolean | Uint8Array)[] + ): T[] { + if (!this.isBuilt()) { + throw new Error('Cache not built'); + } + + return this.db!.prepare(sql).all(...params) as T[]; + } + + /** + * Execute a raw SQL query and return a single row + * Use this in your query functions in pcd/queries/*.ts + */ + queryOne( + sql: string, + ...params: (string | number | null | boolean | Uint8Array)[] + ): T | undefined { + if (!this.isBuilt()) { + throw new Error('Cache not built'); + } + + return this.db!.prepare(sql).get(...params) as T | undefined; + } + + /** + * Validate SQL statements by doing a dry-run in a transaction + * Returns null if valid, or an error message if invalid + * + * This is a safety check before writing operations to files. + * It catches FK violations, constraint errors, etc. + */ + validateSql(sqlStatements: string[]): ValidationResult { + if (!this.isBuilt()) { + return { valid: false, error: 'Cache not built' }; + } + + try { + // Start a savepoint (nested transaction) + this.db!.exec('SAVEPOINT validation_check'); + + try { + // Try to execute each statement + for (const sql of sqlStatements) { + this.db!.exec(sql); + } + + // All statements executed successfully + return { valid: true }; + } finally { + // Always rollback - this is just a validation check + this.db!.exec('ROLLBACK TO SAVEPOINT validation_check'); + this.db!.exec('RELEASE SAVEPOINT validation_check'); + } + } catch (error) { + // Parse the error to provide a helpful message + const errorStr = String(error); + + // Common SQLite constraint errors + if (errorStr.includes('FOREIGN KEY constraint failed')) { + return { + valid: false, + error: `Foreign key constraint failed - referenced entity does not exist. ${errorStr}` + }; + } + if (errorStr.includes('UNIQUE constraint failed')) { + return { + valid: false, + error: `Unique constraint failed - duplicate entry. ${errorStr}` + }; + } + if (errorStr.includes('NOT NULL constraint failed')) { + return { + valid: false, + error: `Required field is missing. ${errorStr}` + }; + } + if (errorStr.includes('CHECK constraint failed')) { + return { + valid: false, + error: `Value validation failed. ${errorStr}` + }; + } + + return { + valid: false, + error: `Database validation failed: ${errorStr}` + }; + } + } +} diff --git a/src/lib/server/pcd/database/compiler.ts b/src/lib/server/pcd/database/compiler.ts new file mode 100644 index 0000000..994cf54 --- /dev/null +++ b/src/lib/server/pcd/database/compiler.ts @@ -0,0 +1,53 @@ +/** + * PCD Database Compiler + * Handles compiling and invalidating PCD caches + */ + +import { PCDCache } from './cache.ts'; +import { setCache, getCache, deleteCache, getCachedDatabaseIds } from './registry.ts'; +import type { CacheBuildStats } from '../core/types.ts'; + +/** + * Compile a PCD into an in-memory cache + * Returns build stats for logging + */ +export async function compile( + pcdPath: string, + databaseInstanceId: number +): Promise { + // Close existing cache if present + const existing = getCache(databaseInstanceId); + if (existing) { + existing.close(); + } + + // Create and build new cache + const cache = new PCDCache(pcdPath, databaseInstanceId); + const stats = await cache.build(); + + // Store in registry + setCache(databaseInstanceId, cache); + + return stats; +} + +/** + * Invalidate a cache (close and remove from registry) + */ +export function invalidate(databaseInstanceId: number): void { + const cache = getCache(databaseInstanceId); + if (cache) { + cache.close(); + deleteCache(databaseInstanceId); + } +} + +/** + * Invalidate all caches + */ +export function invalidateAll(): void { + const ids = getCachedDatabaseIds(); + for (const id of ids) { + invalidate(id); + } +} diff --git a/src/lib/server/pcd/database/registry.ts b/src/lib/server/pcd/database/registry.ts new file mode 100644 index 0000000..f9f8893 --- /dev/null +++ b/src/lib/server/pcd/database/registry.ts @@ -0,0 +1,56 @@ +/** + * PCD Cache Registry + * Manages the global registry of compiled PCD caches + */ + +import type { PCDCache } from './cache.ts'; + +/** + * Cache registry - maps database instance ID to PCDCache + */ +const caches = new Map(); + +/** + * Set a cache in the registry + */ +export function setCache(databaseInstanceId: number, cache: PCDCache): void { + caches.set(databaseInstanceId, cache); +} + +/** + * Get a compiled cache by database instance ID + */ +export function getCache(databaseInstanceId: number): PCDCache | undefined { + return caches.get(databaseInstanceId); +} + +/** + * Check if a cache exists for a database instance + */ +export function hasCache(databaseInstanceId: number): boolean { + return caches.has(databaseInstanceId); +} + +/** + * Delete a cache from the registry + */ +export function deleteCache(databaseInstanceId: number): boolean { + return caches.delete(databaseInstanceId); +} + +/** + * Get all currently cached database instance IDs (for debugging) + */ +export function getCachedDatabaseIds(): number[] { + return Array.from(caches.keys()); +} + +/** + * Clear all caches from the registry + */ +export function clearAllCaches(): void { + for (const cache of caches.values()) { + cache.close(); + } + caches.clear(); +} diff --git a/src/lib/server/pcd/deps.ts b/src/lib/server/pcd/deps.ts deleted file mode 100644 index cbb1f31..0000000 --- a/src/lib/server/pcd/deps.ts +++ /dev/null @@ -1,167 +0,0 @@ -/** - * PCD Dependency Resolution - * Handles cloning and managing PCD dependencies - */ - -import { Git, clone } from '$utils/git/index.ts'; -import { loadManifest } from './manifest.ts'; - -/** - * Extract repository name from GitHub URL - * https://github.com/Dictionarry-Hub/schema -> schema - */ -function getRepoName(repoUrl: string): string { - const parts = repoUrl.split('/'); - return parts[parts.length - 1]; -} - -/** - * Get dependency path - */ -function getDependencyPath(pcdPath: string, repoName: string): string { - return `${pcdPath}/deps/${repoName}`; -} - -/** - * Clone and checkout a single dependency - */ -async function cloneDependency(pcdPath: string, repoUrl: string, version: string): Promise { - const repoName = getRepoName(repoUrl); - const depPath = getDependencyPath(pcdPath, repoName); - - // Clone the dependency repository - await clone(repoUrl, depPath); - - // Checkout the specific version tag - const git = new Git(depPath); - await git.checkout(version); - - // Clean up dependency - keep only ops folder and pcd.json - const keepItems = new Set(['ops', 'pcd.json']); - - for await (const entry of Deno.readDir(depPath)) { - if (!keepItems.has(entry.name)) { - const itemPath = `${depPath}/${entry.name}`; - await Deno.remove(itemPath, { recursive: true }); - } - } -} - -/** - * Process all dependencies for a PCD - * Clones dependencies and validates their manifests - */ -export async function processDependencies(pcdPath: string): Promise { - // Load the PCD's manifest - const manifest = await loadManifest(pcdPath); - - // Skip if no dependencies - if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { - return; - } - - // Create deps directory - const depsDir = `${pcdPath}/deps`; - await Deno.mkdir(depsDir, { recursive: true }); - - // Process each dependency - for (const [repoUrl, version] of Object.entries(manifest.dependencies)) { - // Clone and checkout the dependency - await cloneDependency(pcdPath, repoUrl, version); - - // Validate the dependency's manifest - const repoName = getRepoName(repoUrl); - const depPath = getDependencyPath(pcdPath, repoName); - await loadManifest(depPath); - - // TODO (post-2.0): Recursively process nested dependencies - // For now, we only support one level of dependencies - } -} - -/** - * Get the installed version of a dependency from its manifest - */ -async function getInstalledVersion(pcdPath: string, repoName: string): Promise { - const depManifestPath = `${pcdPath}/deps/${repoName}/pcd.json`; - try { - const content = await Deno.readTextFile(depManifestPath); - const manifest = JSON.parse(content); - return manifest.version ?? null; - } catch { - return null; - } -} - -/** - * Sync dependencies - update any that have changed versions in the manifest - * Called after pulling updates to ensure dependencies match manifest requirements - */ -export async function syncDependencies(pcdPath: string): Promise { - const manifest = await loadManifest(pcdPath); - - if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { - return; - } - - // Ensure deps directory exists - const depsDir = `${pcdPath}/deps`; - await Deno.mkdir(depsDir, { recursive: true }); - - for (const [repoUrl, requiredVersion] of Object.entries(manifest.dependencies)) { - const repoName = getRepoName(repoUrl); - const depPath = getDependencyPath(pcdPath, repoName); - const installedVersion = await getInstalledVersion(pcdPath, repoName); - - if (installedVersion === requiredVersion) { - // Already at correct version, skip - continue; - } - - // Version changed or not installed - remove old and clone new - try { - await Deno.remove(depPath, { recursive: true }); - } catch { - // Didn't exist, that's fine - } - - // Clone and checkout the new version - await cloneDependency(pcdPath, repoUrl, requiredVersion); - - // Validate the dependency's manifest - await loadManifest(depPath); - } -} - -/** - * Check if all dependencies are present and valid - */ -export async function validateDependencies(pcdPath: string): Promise { - try { - const manifest = await loadManifest(pcdPath); - - // If no dependencies, validation passes - if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { - return true; - } - - for (const [repoUrl] of Object.entries(manifest.dependencies)) { - const repoName = getRepoName(repoUrl); - const depPath = getDependencyPath(pcdPath, repoName); - - // Check if dependency directory exists - try { - await Deno.stat(depPath); - } catch { - return false; - } - - // Validate dependency manifest - await loadManifest(depPath); - } - - return true; - } catch { - return false; - } -} diff --git a/src/lib/server/pcd/entities/customFormats/conditions/read.ts b/src/lib/server/pcd/entities/customFormats/conditions/read.ts index ceb0ed8..551ddb1 100644 --- a/src/lib/server/pcd/entities/customFormats/conditions/read.ts +++ b/src/lib/server/pcd/entities/customFormats/conditions/read.ts @@ -2,7 +2,7 @@ * Custom format condition read queries for test evaluation */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { ConditionData, ConditionListItem, CustomFormatWithConditions } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/customFormats/conditions/update.ts b/src/lib/server/pcd/entities/customFormats/conditions/update.ts index 663fa09..663b81b 100644 --- a/src/lib/server/pcd/entities/customFormats/conditions/update.ts +++ b/src/lib/server/pcd/entities/customFormats/conditions/update.ts @@ -7,8 +7,8 @@ * - Updating existing conditions */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { ConditionData } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/entities/customFormats/create.ts b/src/lib/server/pcd/entities/customFormats/create.ts index 10df5be..568f01d 100644 --- a/src/lib/server/pcd/entities/customFormats/create.ts +++ b/src/lib/server/pcd/entities/customFormats/create.ts @@ -2,8 +2,8 @@ * Create a custom format operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface CreateCustomFormatInput { name: string; diff --git a/src/lib/server/pcd/entities/customFormats/delete.ts b/src/lib/server/pcd/entities/customFormats/delete.ts index 259e4d7..7797c46 100644 --- a/src/lib/server/pcd/entities/customFormats/delete.ts +++ b/src/lib/server/pcd/entities/customFormats/delete.ts @@ -2,8 +2,8 @@ * Delete a custom format operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface DeleteCustomFormatOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/customFormats/general/read.ts b/src/lib/server/pcd/entities/customFormats/general/read.ts index 3ed3087..01350f0 100644 --- a/src/lib/server/pcd/entities/customFormats/general/read.ts +++ b/src/lib/server/pcd/entities/customFormats/general/read.ts @@ -2,7 +2,7 @@ * Custom format general read queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { CustomFormatGeneral } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/customFormats/general/update.ts b/src/lib/server/pcd/entities/customFormats/general/update.ts index dbd2106..542d485 100644 --- a/src/lib/server/pcd/entities/customFormats/general/update.ts +++ b/src/lib/server/pcd/entities/customFormats/general/update.ts @@ -2,8 +2,8 @@ * Update custom format general information */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { CustomFormatGeneral } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/entities/customFormats/list.ts b/src/lib/server/pcd/entities/customFormats/list.ts index e40e8de..6a5332b 100644 --- a/src/lib/server/pcd/entities/customFormats/list.ts +++ b/src/lib/server/pcd/entities/customFormats/list.ts @@ -2,7 +2,7 @@ * Custom format list queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { Tag, CustomFormatTableRow, ConditionRef } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/customFormats/tests/create.ts b/src/lib/server/pcd/entities/customFormats/tests/create.ts index 6bf688f..63897fb 100644 --- a/src/lib/server/pcd/entities/customFormats/tests/create.ts +++ b/src/lib/server/pcd/entities/customFormats/tests/create.ts @@ -2,7 +2,7 @@ * Create a custom format test operation */ -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface CreateTestInput { title: string; diff --git a/src/lib/server/pcd/entities/customFormats/tests/delete.ts b/src/lib/server/pcd/entities/customFormats/tests/delete.ts index 7ef1477..7b99855 100644 --- a/src/lib/server/pcd/entities/customFormats/tests/delete.ts +++ b/src/lib/server/pcd/entities/customFormats/tests/delete.ts @@ -2,7 +2,7 @@ * Delete a custom format test operation */ -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { CustomFormatTest } from '$shared/pcd/display.ts'; interface DeleteTestOptions { diff --git a/src/lib/server/pcd/entities/customFormats/tests/read.ts b/src/lib/server/pcd/entities/customFormats/tests/read.ts index eb2e0a4..d50e0e9 100644 --- a/src/lib/server/pcd/entities/customFormats/tests/read.ts +++ b/src/lib/server/pcd/entities/customFormats/tests/read.ts @@ -2,7 +2,7 @@ * Custom format test read queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { CustomFormatBasic, CustomFormatTest } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/customFormats/tests/update.ts b/src/lib/server/pcd/entities/customFormats/tests/update.ts index c543443..fa02ae4 100644 --- a/src/lib/server/pcd/entities/customFormats/tests/update.ts +++ b/src/lib/server/pcd/entities/customFormats/tests/update.ts @@ -2,7 +2,7 @@ * Update a custom format test operation */ -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { CustomFormatTest } from '$shared/pcd/display.ts'; interface UpdateTestInput { diff --git a/src/lib/server/pcd/entities/delayProfiles/create.ts b/src/lib/server/pcd/entities/delayProfiles/create.ts index 798209e..65d37da 100644 --- a/src/lib/server/pcd/entities/delayProfiles/create.ts +++ b/src/lib/server/pcd/entities/delayProfiles/create.ts @@ -2,8 +2,8 @@ * Create a delay profile operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { PreferredProtocol } from '$shared/pcd/display.ts'; interface CreateDelayProfileInput { diff --git a/src/lib/server/pcd/entities/delayProfiles/delete.ts b/src/lib/server/pcd/entities/delayProfiles/delete.ts index c7e90f7..4a0ba18 100644 --- a/src/lib/server/pcd/entities/delayProfiles/delete.ts +++ b/src/lib/server/pcd/entities/delayProfiles/delete.ts @@ -2,8 +2,8 @@ * Delete a delay profile operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { DelayProfilesRow } from '$shared/pcd/display.ts'; interface DeleteDelayProfileOptions { diff --git a/src/lib/server/pcd/entities/delayProfiles/read.ts b/src/lib/server/pcd/entities/delayProfiles/read.ts index 9f0b0f6..0de0c66 100644 --- a/src/lib/server/pcd/entities/delayProfiles/read.ts +++ b/src/lib/server/pcd/entities/delayProfiles/read.ts @@ -6,7 +6,7 @@ * Delay profile read operations */ -import type { PCDCache } from '../../cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { DelayProfilesRow, PreferredProtocol } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/delayProfiles/update.ts b/src/lib/server/pcd/entities/delayProfiles/update.ts index 8d455fb..be40139 100644 --- a/src/lib/server/pcd/entities/delayProfiles/update.ts +++ b/src/lib/server/pcd/entities/delayProfiles/update.ts @@ -2,8 +2,8 @@ * Update a delay profile operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { DelayProfilesRow, PreferredProtocol } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/entities/mediaManagement/media-settings/create.ts b/src/lib/server/pcd/entities/mediaManagement/media-settings/create.ts index 0f69ab6..a19077d 100644 --- a/src/lib/server/pcd/entities/mediaManagement/media-settings/create.ts +++ b/src/lib/server/pcd/entities/mediaManagement/media-settings/create.ts @@ -2,8 +2,8 @@ * Create media settings config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RadarrMediaSettingsRow } from '$shared/pcd/display.ts'; export interface CreateMediaSettingsInput { diff --git a/src/lib/server/pcd/entities/mediaManagement/media-settings/delete.ts b/src/lib/server/pcd/entities/mediaManagement/media-settings/delete.ts index 8fd3181..c778f26 100644 --- a/src/lib/server/pcd/entities/mediaManagement/media-settings/delete.ts +++ b/src/lib/server/pcd/entities/mediaManagement/media-settings/delete.ts @@ -2,8 +2,8 @@ * Remove media settings config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; export interface RemoveMediaSettingsOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/mediaManagement/media-settings/read.ts b/src/lib/server/pcd/entities/mediaManagement/media-settings/read.ts index 5cdd681..c225c01 100644 --- a/src/lib/server/pcd/entities/mediaManagement/media-settings/read.ts +++ b/src/lib/server/pcd/entities/mediaManagement/media-settings/read.ts @@ -2,7 +2,7 @@ * Media settings read operations (list and get) */ -import type { PCDCache } from '../../../cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { RadarrMediaSettingsRow, SonarrMediaSettingsRow, MediaSettingsListItem } from '$shared/pcd/display.ts'; export async function list(cache: PCDCache): Promise { diff --git a/src/lib/server/pcd/entities/mediaManagement/media-settings/update.ts b/src/lib/server/pcd/entities/mediaManagement/media-settings/update.ts index e635b89..b51da86 100644 --- a/src/lib/server/pcd/entities/mediaManagement/media-settings/update.ts +++ b/src/lib/server/pcd/entities/mediaManagement/media-settings/update.ts @@ -2,8 +2,8 @@ * Update media settings config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RadarrMediaSettingsRow } from '$shared/pcd/display.ts'; export interface UpdateMediaSettingsInput { diff --git a/src/lib/server/pcd/entities/mediaManagement/naming/create.ts b/src/lib/server/pcd/entities/mediaManagement/naming/create.ts index 639264f..2951ead 100644 --- a/src/lib/server/pcd/entities/mediaManagement/naming/create.ts +++ b/src/lib/server/pcd/entities/mediaManagement/naming/create.ts @@ -2,8 +2,8 @@ * Create naming config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RadarrNamingRow, SonarrNamingRow } from '$shared/pcd/display.ts'; import { colonReplacementToDb, multiEpisodeStyleToDb } from '$shared/pcd/mediaManagement.ts'; diff --git a/src/lib/server/pcd/entities/mediaManagement/naming/delete.ts b/src/lib/server/pcd/entities/mediaManagement/naming/delete.ts index be618d6..2774ce6 100644 --- a/src/lib/server/pcd/entities/mediaManagement/naming/delete.ts +++ b/src/lib/server/pcd/entities/mediaManagement/naming/delete.ts @@ -2,8 +2,8 @@ * Remove naming config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; export interface RemoveRadarrNamingOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/mediaManagement/naming/read.ts b/src/lib/server/pcd/entities/mediaManagement/naming/read.ts index dd17663..0854161 100644 --- a/src/lib/server/pcd/entities/mediaManagement/naming/read.ts +++ b/src/lib/server/pcd/entities/mediaManagement/naming/read.ts @@ -2,7 +2,7 @@ * Naming read operations (list and get) */ -import type { PCDCache } from '../../../cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { RadarrNamingRow, SonarrNamingRow, NamingListItem } from '$shared/pcd/display.ts'; import { colonReplacementFromDb, multiEpisodeStyleFromDb } from '$shared/pcd/mediaManagement.ts'; diff --git a/src/lib/server/pcd/entities/mediaManagement/naming/update.ts b/src/lib/server/pcd/entities/mediaManagement/naming/update.ts index 5cedd30..b1f7761 100644 --- a/src/lib/server/pcd/entities/mediaManagement/naming/update.ts +++ b/src/lib/server/pcd/entities/mediaManagement/naming/update.ts @@ -2,8 +2,8 @@ * Update naming config operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RadarrNamingRow, SonarrNamingRow } from '$shared/pcd/display.ts'; import { colonReplacementToDb, multiEpisodeStyleToDb } from '$shared/pcd/mediaManagement.ts'; diff --git a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/create.ts b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/create.ts index cc3b8ab..d2c230e 100644 --- a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/create.ts +++ b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/create.ts @@ -2,8 +2,8 @@ * Quality definitions create operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { QualityDefinitionEntry } from '$shared/pcd/display.ts'; export interface CreateQualityDefinitionsInput { diff --git a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/delete.ts b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/delete.ts index a8d4e08..dc04584 100644 --- a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/delete.ts +++ b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/delete.ts @@ -2,8 +2,8 @@ * Quality definitions remove operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; export interface RemoveQualityDefinitionsOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/read.ts b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/read.ts index 722f84b..c81ff7d 100644 --- a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/read.ts +++ b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/read.ts @@ -2,7 +2,7 @@ * Quality definitions read operations */ -import type { PCDCache } from '../../../cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { ArrType } from '$shared/pcd/types.ts'; import type { QualityDefinitionListItem, diff --git a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/update.ts b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/update.ts index 1d52124..9587a84 100644 --- a/src/lib/server/pcd/entities/mediaManagement/quality-definitions/update.ts +++ b/src/lib/server/pcd/entities/mediaManagement/quality-definitions/update.ts @@ -2,8 +2,8 @@ * Quality definitions update operations */ -import type { PCDCache } from '../../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { QualityDefinitionEntry } from '$shared/pcd/display.ts'; export interface UpdateQualityDefinitionsInput { diff --git a/src/lib/server/pcd/entities/qualityProfiles/create.ts b/src/lib/server/pcd/entities/qualityProfiles/create.ts index 5de6ee6..74d1c66 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/create.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/create.ts @@ -2,8 +2,8 @@ * Create a quality profile operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; // ============================================================================ // Input types diff --git a/src/lib/server/pcd/entities/qualityProfiles/delete.ts b/src/lib/server/pcd/entities/qualityProfiles/delete.ts index f1b38de..ac2e384 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/delete.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/delete.ts @@ -2,8 +2,8 @@ * Delete a quality profile operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; // ============================================================================ // Input types diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/create.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/create.ts index 13bf149..7e6f109 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/create.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/create.ts @@ -2,8 +2,8 @@ * Create test entity operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface CreateEntityInput { type: 'movie' | 'series'; diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/delete.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/delete.ts index 4350486..756cd15 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/delete.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/delete.ts @@ -2,8 +2,8 @@ * Delete test entity operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface DeleteEntityOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/read.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/read.ts index 7243030..ebcbf7d 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/read.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/read.ts @@ -2,7 +2,7 @@ * Entity test read queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { TestEntity } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/create.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/create.ts index 68ebbb0..2b9ef62 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/create.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/create.ts @@ -2,8 +2,8 @@ * Create test release operations */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface CreateReleaseInput { entityType: 'movie' | 'series'; diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/delete.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/delete.ts index a391c3c..ee2e5ad 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/delete.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/delete.ts @@ -2,8 +2,8 @@ * Delete test release operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface DeleteReleaseOptions { databaseId: number; diff --git a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/update.ts b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/update.ts index a570256..890b778 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/update.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/entityTests/releases/update.ts @@ -2,8 +2,8 @@ * Update test release operation */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface UpdateReleaseInput { id: number; diff --git a/src/lib/server/pcd/entities/qualityProfiles/general/read.ts b/src/lib/server/pcd/entities/qualityProfiles/general/read.ts index b489098..9f9054e 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/general/read.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/general/read.ts @@ -2,7 +2,7 @@ * Quality profile general queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { QualityProfileGeneral, QualityProfileLanguages } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/qualityProfiles/general/update.ts b/src/lib/server/pcd/entities/qualityProfiles/general/update.ts index b18eba5..1484a77 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/general/update.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/general/update.ts @@ -2,8 +2,8 @@ * Update quality profile general information and languages */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { QualityProfileGeneral } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/entities/qualityProfiles/list.ts b/src/lib/server/pcd/entities/qualityProfiles/list.ts index 0ace514..3e5b9b2 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/list.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/list.ts @@ -2,7 +2,7 @@ * Quality profile list queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { Tag, QualityProfileTableRow, diff --git a/src/lib/server/pcd/entities/qualityProfiles/qualities/read.ts b/src/lib/server/pcd/entities/qualityProfiles/qualities/read.ts index bf4c701..5dcca3c 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/qualities/read.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/qualities/read.ts @@ -2,7 +2,7 @@ * Quality profile qualities queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { QualitiesPageData, OrderedItem, QualitiesGroup } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/qualityProfiles/qualities/update.ts b/src/lib/server/pcd/entities/qualityProfiles/qualities/update.ts index 7c7793b..742114e 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/qualities/update.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/qualities/update.ts @@ -2,8 +2,8 @@ * Update quality profile qualities */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { OrderedItem } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/entities/qualityProfiles/scoring/read.ts b/src/lib/server/pcd/entities/qualityProfiles/scoring/read.ts index 51e9efb..32bc49e 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/scoring/read.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/scoring/read.ts @@ -2,7 +2,7 @@ * Quality profile scoring queries */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { QualityProfileScoring, ProfileCfScores, AllCfScoresResult } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/qualityProfiles/scoring/update.ts b/src/lib/server/pcd/entities/qualityProfiles/scoring/update.ts index c8055f3..8590612 100644 --- a/src/lib/server/pcd/entities/qualityProfiles/scoring/update.ts +++ b/src/lib/server/pcd/entities/qualityProfiles/scoring/update.ts @@ -2,8 +2,8 @@ * Update quality profile scoring settings */ -import type { PCDCache } from '$pcd/cache.ts'; -import { writeOperation, type OperationLayer } from '$pcd/writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; // ============================================================================ diff --git a/src/lib/server/pcd/entities/regularExpressions/create.ts b/src/lib/server/pcd/entities/regularExpressions/create.ts index 288f595..3357348 100644 --- a/src/lib/server/pcd/entities/regularExpressions/create.ts +++ b/src/lib/server/pcd/entities/regularExpressions/create.ts @@ -2,8 +2,8 @@ * Create a regular expression operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; interface CreateRegularExpressionInput { name: string; diff --git a/src/lib/server/pcd/entities/regularExpressions/delete.ts b/src/lib/server/pcd/entities/regularExpressions/delete.ts index 4dfc683..c38d2fb 100644 --- a/src/lib/server/pcd/entities/regularExpressions/delete.ts +++ b/src/lib/server/pcd/entities/regularExpressions/delete.ts @@ -2,8 +2,8 @@ * Delete a regular expression operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RegularExpressionWithTags } from '$shared/pcd/display.ts'; interface DeleteRegularExpressionOptions { diff --git a/src/lib/server/pcd/entities/regularExpressions/read.ts b/src/lib/server/pcd/entities/regularExpressions/read.ts index 378ecb2..a70efb2 100644 --- a/src/lib/server/pcd/entities/regularExpressions/read.ts +++ b/src/lib/server/pcd/entities/regularExpressions/read.ts @@ -2,7 +2,7 @@ * Regular expression read operations */ -import type { PCDCache } from '../../cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { Tag, RegularExpressionWithTags } from '$shared/pcd/display.ts'; /** diff --git a/src/lib/server/pcd/entities/regularExpressions/update.ts b/src/lib/server/pcd/entities/regularExpressions/update.ts index ab676d9..7fbd506 100644 --- a/src/lib/server/pcd/entities/regularExpressions/update.ts +++ b/src/lib/server/pcd/entities/regularExpressions/update.ts @@ -2,8 +2,8 @@ * Update a regular expression operation */ -import type { PCDCache } from '../../cache.ts'; -import { writeOperation, type OperationLayer } from '../../writer.ts'; +import type { PCDCache } from '$pcd/index.ts'; +import { writeOperation, type OperationLayer } from '$pcd/index.ts'; import type { RegularExpressionWithTags } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/lib/server/pcd/git/dependencies.ts b/src/lib/server/pcd/git/dependencies.ts new file mode 100644 index 0000000..6455e32 --- /dev/null +++ b/src/lib/server/pcd/git/dependencies.ts @@ -0,0 +1,235 @@ +/** + * PCD Dependency Resolution + * Handles cloning and managing PCD dependencies using git tags + */ + +import { Git, clone } from '$utils/git/index.ts'; +import { loadManifest } from '../manifest/manifest.ts'; +import { logger } from '$logger/logger.ts'; + +/** + * Extract repository name from GitHub URL + * https://github.com/Dictionarry-Hub/schema -> schema + */ +function getRepoName(repoUrl: string): string { + const parts = repoUrl.split('/'); + return parts[parts.length - 1]; +} + +/** + * Get dependency path + */ +function getDependencyPath(pcdPath: string, repoName: string): string { + return `${pcdPath}/deps/${repoName}`; +} + +/** + * Check if a directory exists + */ +async function dirExists(path: string): Promise { + try { + const stat = await Deno.stat(path); + return stat.isDirectory; + } catch { + return false; + } +} + +/** + * Clone and checkout a dependency at a specific tag + * Keeps .git, ops, and pcd.json - removes everything else + */ +async function cloneDependency(pcdPath: string, repoUrl: string, version: string): Promise { + const repoName = getRepoName(repoUrl); + const depPath = getDependencyPath(pcdPath, repoName); + + // Clone the dependency repository + await clone(repoUrl, depPath); + + // Checkout the specific version tag + const git = new Git(depPath); + await git.checkout(version); + + // Clean up dependency - keep only .git, ops folder and pcd.json + const keepItems = new Set(['.git', 'ops', 'pcd.json']); + + for await (const entry of Deno.readDir(depPath)) { + if (!keepItems.has(entry.name)) { + const itemPath = `${depPath}/${entry.name}`; + await Deno.remove(itemPath, { recursive: true }); + } + } +} + +/** + * Get the installed version of a dependency from its manifest + */ +async function getInstalledVersion(pcdPath: string, repoName: string): Promise { + const depManifestPath = `${pcdPath}/deps/${repoName}/pcd.json`; + try { + const content = await Deno.readTextFile(depManifestPath); + const manifest = JSON.parse(content); + return manifest.version ?? null; + } catch { + return null; + } +} + +/** + * Update a dependency to a new version using fetch + checkout + */ +async function updateDependency(depPath: string, version: string): Promise { + const git = new Git(depPath); + await git.fetchTags(); + await git.checkout(version); +} + +/** + * Process all dependencies for a PCD (initial clone) + * Called when linking a new database + */ +export async function processDependencies(pcdPath: string): Promise { + const manifest = await loadManifest(pcdPath); + + if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { + return; + } + + // Create deps directory + const depsDir = `${pcdPath}/deps`; + await Deno.mkdir(depsDir, { recursive: true }); + + for (const [repoUrl, version] of Object.entries(manifest.dependencies)) { + const repoName = getRepoName(repoUrl); + const depPath = getDependencyPath(pcdPath, repoName); + + // Clone and checkout the dependency + await cloneDependency(pcdPath, repoUrl, version); + + // Validate the dependency's manifest + await loadManifest(depPath); + + await logger.debug(`Installed dependency ${repoName}@${version}`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName, version } + }); + } +} + +/** + * Sync dependencies - update any that have changed versions + * Uses fetch + checkout instead of re-cloning + */ +export async function syncDependencies(pcdPath: string): Promise { + const manifest = await loadManifest(pcdPath); + + if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { + return; + } + + const depsDir = `${pcdPath}/deps`; + await Deno.mkdir(depsDir, { recursive: true }); + + for (const [repoUrl, requiredVersion] of Object.entries(manifest.dependencies)) { + const repoName = getRepoName(repoUrl); + const depPath = getDependencyPath(pcdPath, repoName); + const installedVersion = await getInstalledVersion(pcdPath, repoName); + + // Already at correct version + if (installedVersion === requiredVersion) { + continue; + } + + // Check if dependency exists with .git folder + const hasGitFolder = await dirExists(`${depPath}/.git`); + + if (hasGitFolder) { + // Fetch tags and checkout new version + await updateDependency(depPath, requiredVersion); + await logger.info(`Updated dependency ${repoName}: ${installedVersion} -> ${requiredVersion}`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName, from: installedVersion, to: requiredVersion } + }); + } else { + // No .git folder (legacy or corrupted) - re-clone + try { + await Deno.remove(depPath, { recursive: true }); + } catch { + // Didn't exist + } + await cloneDependency(pcdPath, repoUrl, requiredVersion); + await logger.info(`Re-cloned dependency ${repoName}@${requiredVersion}`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName, version: requiredVersion } + }); + } + + // Validate the dependency's manifest + await loadManifest(depPath); + } +} + +/** + * Validate and fix dependencies on startup + * Ensures all deps exist and are at the correct version + */ +export async function validateDependencies(pcdPath: string): Promise { + try { + const manifest = await loadManifest(pcdPath); + + if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) { + return true; + } + + let allValid = true; + + for (const [repoUrl, requiredVersion] of Object.entries(manifest.dependencies)) { + const repoName = getRepoName(repoUrl); + const depPath = getDependencyPath(pcdPath, repoName); + + // Check if dependency exists + if (!(await dirExists(depPath))) { + await logger.warn(`Missing dependency ${repoName}, will install`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName } + }); + allValid = false; + continue; + } + + // Check version + const installedVersion = await getInstalledVersion(pcdPath, repoName); + if (installedVersion !== requiredVersion) { + await logger.warn(`Dependency ${repoName} version mismatch: ${installedVersion} != ${requiredVersion}`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName, installed: installedVersion, required: requiredVersion } + }); + allValid = false; + } + + // Validate manifest + try { + await loadManifest(depPath); + } catch { + await logger.warn(`Dependency ${repoName} has invalid manifest`, { + source: 'PCDDependencies', + meta: { pcdPath, repoName } + }); + allValid = false; + } + } + + // If any issues found, run sync to fix them + if (!allValid) { + await syncDependencies(pcdPath); + } + + return true; + } catch (error) { + await logger.error('Failed to validate dependencies', { + source: 'PCDDependencies', + meta: { pcdPath, error: String(error) } + }); + return false; + } +} diff --git a/src/lib/server/pcd/index.ts b/src/lib/server/pcd/index.ts new file mode 100644 index 0000000..1450709 --- /dev/null +++ b/src/lib/server/pcd/index.ts @@ -0,0 +1,75 @@ +/** + * PCD Public API + * Re-exports for external consumers + */ + +// ============================================================================ +// MANAGER +// ============================================================================ + +export { pcdManager } from './core/manager.ts'; + +// ============================================================================ +// CACHE +// ============================================================================ + +export { PCDCache } from './database/cache.ts'; +export { getCache, getCachedDatabaseIds } from './database/registry.ts'; +export { compile, invalidate, invalidateAll } from './database/compiler.ts'; + +// ============================================================================ +// WRITER +// ============================================================================ + +export { writeOperation, canWriteToBase } from './operations/writer.ts'; + +// ============================================================================ +// MANIFEST +// ============================================================================ + +export { loadManifest, readManifest, validateManifest, writeManifest, readReadme, writeReadme } from './manifest/manifest.ts'; +export type { Manifest } from './manifest/manifest.ts'; + +// ============================================================================ +// DEPENDENCIES +// ============================================================================ + +export { processDependencies, syncDependencies, validateDependencies } from './git/dependencies.ts'; + +// ============================================================================ +// OPERATIONS +// ============================================================================ + +export { loadAllOperations, loadOperationsFromDir, validateOperations, getPCDPath, getUserOpsPath, getBaseOpsPath } from './operations/loader.ts'; +export { compiledQueryToSql, formatValue } from './operations/sql.ts'; + +// ============================================================================ +// TYPES +// ============================================================================ + +export type { + CacheBuildStats, + Operation, + OperationLayer, + OperationType, + OperationMetadata, + WritableLayer, + WriteOptions, + WriteResult, + ValidationResult, + LinkOptions, + SyncResult +} from './core/types.ts'; + +// ============================================================================ +// ERRORS +// ============================================================================ + +export { + PCDError, + CacheBuildError, + OperationError, + ValidationError, + DependencyError, + ManifestValidationError +} from './core/errors.ts'; diff --git a/src/lib/server/pcd/manifest.ts b/src/lib/server/pcd/manifest/manifest.ts similarity index 85% rename from src/lib/server/pcd/manifest.ts rename to src/lib/server/pcd/manifest/manifest.ts index ded77d8..4278425 100644 --- a/src/lib/server/pcd/manifest.ts +++ b/src/lib/server/pcd/manifest/manifest.ts @@ -4,6 +4,7 @@ */ import { logger } from '$logger/logger.ts'; +import { ManifestValidationError } from '../core/errors.ts'; export interface Manifest { name: string; @@ -25,13 +26,6 @@ export interface Manifest { }; } -export class ManifestValidationError extends Error { - constructor(message: string) { - super(message); - this.name = 'ManifestValidationError'; - } -} - /** * Read manifest from a PCD repository */ @@ -165,3 +159,32 @@ export async function writeManifest(pcdPath: string, manifest: Manifest): Promis meta: { path: pcdPath, manifest } }); } + +// ============================================================================ +// README HELPERS (merged from readme.ts) +// ============================================================================ + +/** + * Read README from a PCD repository + */ +export async function readReadme(pcdPath: string): Promise { + try { + return await Deno.readTextFile(`${pcdPath}/README.md`); + } catch { + return null; + } +} + +/** + * Write README to a PCD repository + */ +export async function writeReadme(pcdPath: string, content: string): Promise { + await Deno.writeTextFile(`${pcdPath}/README.md`, content); + await logger.info('Wrote README', { + source: 'PCDManifest', + meta: { path: pcdPath, content } + }); +} + +// Re-export error for convenience +export { ManifestValidationError }; diff --git a/src/lib/server/pcd/ops.ts b/src/lib/server/pcd/operations/loader.ts similarity index 87% rename from src/lib/server/pcd/ops.ts rename to src/lib/server/pcd/operations/loader.ts index 8ec12c9..918f161 100644 --- a/src/lib/server/pcd/ops.ts +++ b/src/lib/server/pcd/operations/loader.ts @@ -1,14 +1,10 @@ /** + * PCD Operations Loader * Utilities for loading and managing SQL operations from PCD layers */ -export interface Operation { - filename: string; - filepath: string; - sql: string; - order: number; // Extracted from numeric prefix - layer: 'schema' | 'base' | 'tweaks' | 'user'; -} +import { config } from '$config'; +import type { Operation } from '../core/types.ts'; /** * Check if a path exists @@ -69,7 +65,7 @@ export async function loadOperationsFromDir( * "10.advanced.sql" -> 10 * "allow-DV.sql" -> Infinity (no prefix) */ -function extractOrderFromFilename(filename: string): number { +export function extractOrderFromFilename(filename: string): number { const match = filename.match(/^(\d+)\./); if (match) { return parseInt(match[1], 10); @@ -110,20 +106,6 @@ export async function loadAllOperations(pcdPath: string): Promise { return allOperations; } -/** - * Get the user ops directory path for a PCD - */ -export function getUserOpsPath(pcdPath: string): string { - return `${pcdPath}/user_ops`; -} - -/** - * Get the base ops directory path for a PCD - */ -export function getBaseOpsPath(pcdPath: string): string { - return `${pcdPath}/ops`; -} - /** * Validate that operations can be executed * - Check for empty SQL @@ -152,3 +134,28 @@ export function validateOperations(operations: Operation[]): void { orders.add(op.order); } } + +// ============================================================================ +// PATH HELPERS +// ============================================================================ + +/** + * Get the filesystem path for a PCD repository + */ +export function getPCDPath(uuid: string): string { + return `${config.paths.databases}/${uuid}`; +} + +/** + * Get the user ops directory path for a PCD + */ +export function getUserOpsPath(pcdPath: string): string { + return `${pcdPath}/user_ops`; +} + +/** + * Get the base ops directory path for a PCD + */ +export function getBaseOpsPath(pcdPath: string): string { + return `${pcdPath}/ops`; +} diff --git a/src/lib/server/pcd/operations/sql.ts b/src/lib/server/pcd/operations/sql.ts new file mode 100644 index 0000000..c24589c --- /dev/null +++ b/src/lib/server/pcd/operations/sql.ts @@ -0,0 +1,64 @@ +/** + * PCD SQL Utilities + * SQL compilation and formatting utilities + */ + +import type { CompiledQuery } from 'kysely'; + +/** + * Convert a compiled Kysely query to executable SQL + * Replaces ? placeholders with actual values + * + * Note: We can't use simple string.replace() because parameter values + * might contain '?' characters (e.g., regex patterns like '(?<=...)') + * which would get incorrectly replaced on subsequent iterations. + */ +export function compiledQueryToSql(compiled: CompiledQuery): string { + const sql = compiled.sql; + const params = compiled.parameters as unknown[]; + + if (params.length === 0) { + return sql; + } + + // Build result by finding each ? placeholder and replacing with the next param + // We track our position to avoid replacing ? inside already-substituted values + const result: string[] = []; + let paramIndex = 0; + let i = 0; + + while (i < sql.length) { + if (sql[i] === '?' && paramIndex < params.length) { + // Replace this placeholder with the formatted parameter value + result.push(formatValue(params[paramIndex])); + paramIndex++; + i++; + } else { + result.push(sql[i]); + i++; + } + } + + return result.join(''); +} + +/** + * Format a value for SQL insertion + */ +export function formatValue(value: unknown): string { + if (value === null || value === undefined) { + return 'NULL'; + } + if (typeof value === 'number') { + return String(value); + } + if (typeof value === 'boolean') { + return value ? '1' : '0'; + } + if (typeof value === 'string') { + // Escape single quotes by doubling them + return `'${value.replace(/'/g, "''")}'`; + } + // For other types, convert to string and quote + return `'${String(value).replace(/'/g, "''")}'`; +} diff --git a/src/lib/server/pcd/writer.ts b/src/lib/server/pcd/operations/writer.ts similarity index 75% rename from src/lib/server/pcd/writer.ts rename to src/lib/server/pcd/operations/writer.ts index a9d2d64..3a2f04f 100644 --- a/src/lib/server/pcd/writer.ts +++ b/src/lib/server/pcd/operations/writer.ts @@ -1,107 +1,16 @@ /** - * PCD Operation Writer - Write operations to PCD layers using Kysely + * PCD Operation Writer + * Write operations to PCD layers using Kysely */ -import type { CompiledQuery } from 'kysely'; -import { getBaseOpsPath, getUserOpsPath } from './ops.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { logger } from '$logger/logger.ts'; -import { compile, getCache } from './cache.ts'; import { isFileUncommitted } from '$utils/git/status.ts'; - -export type OperationLayer = 'base' | 'user'; -export type OperationType = 'create' | 'update' | 'delete'; - -/** - * Metadata for an operation - used for optimization and tracking - */ -export interface OperationMetadata { - /** The type of operation */ - operation: OperationType; - /** The entity type (e.g., 'delay_profile', 'quality_profile') */ - entity: string; - /** The entity name (current name for create/update, name being deleted for delete) */ - name: string; - /** Previous name if this is a rename operation */ - previousName?: string; -} - -export interface WriteOptions { - /** The database instance ID */ - databaseId: number; - /** Which layer to write to */ - layer: OperationLayer; - /** Description for the operation (used in filename) */ - description: string; - /** The compiled Kysely queries to write */ - queries: CompiledQuery[]; - /** Metadata for optimization and tracking */ - metadata?: OperationMetadata; -} - -export interface WriteResult { - success: boolean; - filepath?: string; - error?: string; -} - -/** - * Convert a compiled Kysely query to executable SQL - * Replaces ? placeholders with actual values - * - * Note: We can't use simple string.replace() because parameter values - * might contain '?' characters (e.g., regex patterns like '(?<=...)') - * which would get incorrectly replaced on subsequent iterations. - */ -function compiledQueryToSql(compiled: CompiledQuery): string { - const sql = compiled.sql; - const params = compiled.parameters as unknown[]; - - if (params.length === 0) { - return sql; - } - - // Build result by finding each ? placeholder and replacing with the next param - // We track our position to avoid replacing ? inside already-substituted values - const result: string[] = []; - let paramIndex = 0; - let i = 0; - - while (i < sql.length) { - if (sql[i] === '?' && paramIndex < params.length) { - // Replace this placeholder with the formatted parameter value - result.push(formatValue(params[paramIndex])); - paramIndex++; - i++; - } else { - result.push(sql[i]); - i++; - } - } - - return result.join(''); -} - -/** - * Format a value for SQL insertion - */ -function formatValue(value: unknown): string { - if (value === null || value === undefined) { - return 'NULL'; - } - if (typeof value === 'number') { - return String(value); - } - if (typeof value === 'boolean') { - return value ? '1' : '0'; - } - if (typeof value === 'string') { - // Escape single quotes by doubling them - return `'${value.replace(/'/g, "''")}'`; - } - // For other types, convert to string and quote - return `'${String(value).replace(/'/g, "''")}'`; -} +import { getBaseOpsPath, getUserOpsPath } from './loader.ts'; +import { compiledQueryToSql } from './sql.ts'; +import { compile } from '../database/compiler.ts'; +import { getCache } from '../database/registry.ts'; +import type { OperationLayer, OperationMetadata, OperationType, WriteOptions, WriteResult } from '../core/types.ts'; /** * Get the next available operation number for a directory @@ -390,3 +299,6 @@ export function canWriteToBase(databaseId: number): boolean { const instance = databaseInstancesQueries.getById(databaseId); return !!instance?.personal_access_token; } + +// Re-export types for convenience +export type { OperationLayer, OperationType, OperationMetadata, WriteOptions, WriteResult }; diff --git a/src/lib/server/pcd/paths.ts b/src/lib/server/pcd/paths.ts deleted file mode 100644 index 77976b1..0000000 --- a/src/lib/server/pcd/paths.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Helper functions for PCD paths - */ - -import { config } from '$config'; - -/** - * Get the filesystem path for a PCD repository - */ -export function getPCDPath(uuid: string): string { - return `${config.paths.databases}/${uuid}`; -} - -/** - * Get the manifest file path for a PCD repository - */ -export function getManifestPath(uuid: string): string { - return `${getPCDPath(uuid)}/pcd.json`; -} diff --git a/src/lib/server/pcd/readme.ts b/src/lib/server/pcd/readme.ts deleted file mode 100644 index 12edfd2..0000000 --- a/src/lib/server/pcd/readme.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * PCD README Handler - * Handles reading and writing README.md files for PCD repositories - */ - -import { logger } from '$logger/logger.ts'; - -/** - * Read README from a PCD repository - */ -export async function readReadme(pcdPath: string): Promise { - try { - return await Deno.readTextFile(`${pcdPath}/README.md`); - } catch { - return null; - } -} - -/** - * Write README to a PCD repository - */ -export async function writeReadme(pcdPath: string, content: string): Promise { - await Deno.writeTextFile(`${pcdPath}/README.md`, content); - await logger.info('Wrote README', { - source: 'PCDReadme', - meta: { path: pcdPath, content } - }); -} diff --git a/src/lib/server/sync/customFormats/transformer.ts b/src/lib/server/sync/customFormats/transformer.ts index b3eca06..d4afaf8 100644 --- a/src/lib/server/sync/customFormats/transformer.ts +++ b/src/lib/server/sync/customFormats/transformer.ts @@ -3,7 +3,7 @@ * Transforms PCD custom format data to arr API format */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import { type SyncArrType, getSource, diff --git a/src/lib/server/sync/delayProfiles/syncer.ts b/src/lib/server/sync/delayProfiles/syncer.ts index d929314..1a5f91e 100644 --- a/src/lib/server/sync/delayProfiles/syncer.ts +++ b/src/lib/server/sync/delayProfiles/syncer.ts @@ -7,7 +7,7 @@ import { BaseSyncer, type SyncResult } from '../base.ts'; import { arrSyncQueries } from '$db/queries/arrSync.ts'; -import { getCache } from '$pcd/cache.ts'; +import { getCache } from '$pcd/index.ts'; import { get as getDelayProfile } from '$pcd/entities/delayProfiles/index.ts'; import type { DelayProfilesRow } from '$shared/pcd/display.ts'; import type { ArrDelayProfile } from '$arr/types.ts'; diff --git a/src/lib/server/sync/mediaManagement/syncer.ts b/src/lib/server/sync/mediaManagement/syncer.ts index 41375ef..64f3e56 100644 --- a/src/lib/server/sync/mediaManagement/syncer.ts +++ b/src/lib/server/sync/mediaManagement/syncer.ts @@ -16,7 +16,7 @@ import { BaseSyncer, type SyncResult } from '../base.ts'; import { arrSyncQueries } from '$db/queries/arrSync.ts'; -import { getCache, type PCDCache } from '$pcd/cache.ts'; +import { getCache, type PCDCache } from '$pcd/index.ts'; import { getRadarrByName as getRadarrMediaSettings, getSonarrByName as getSonarrMediaSettings } from '$pcd/entities/mediaManagement/media-settings/read.ts'; import { getRadarrByName as getRadarrNaming, getSonarrByName as getSonarrNaming } from '$pcd/entities/mediaManagement/naming/read.ts'; import { getRadarrByName as getRadarrQualityDefs, getSonarrByName as getSonarrQualityDefs } from '$pcd/entities/mediaManagement/quality-definitions/read.ts'; diff --git a/src/lib/server/sync/qualityProfiles/syncer.ts b/src/lib/server/sync/qualityProfiles/syncer.ts index d173390..177ce29 100644 --- a/src/lib/server/sync/qualityProfiles/syncer.ts +++ b/src/lib/server/sync/qualityProfiles/syncer.ts @@ -13,7 +13,7 @@ import { BaseSyncer, type SyncResult } from '../base.ts'; import { arrSyncQueries } from '$db/queries/arrSync.ts'; -import { getCache, getCachedDatabaseIds } from '$pcd/cache.ts'; +import { getCache, getCachedDatabaseIds } from '$pcd/index.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { logger } from '$logger/logger.ts'; import type { SyncArrType } from '../mappings.ts'; diff --git a/src/lib/server/sync/qualityProfiles/transformer.ts b/src/lib/server/sync/qualityProfiles/transformer.ts index 260c4b2..363330b 100644 --- a/src/lib/server/sync/qualityProfiles/transformer.ts +++ b/src/lib/server/sync/qualityProfiles/transformer.ts @@ -3,7 +3,7 @@ * Transforms PCD quality profile data to arr API format */ -import type { PCDCache } from '$pcd/cache.ts'; +import type { PCDCache } from '$pcd/index.ts'; import type { ArrQualityProfileItem, ArrQualityProfilePayload, diff --git a/src/lib/server/utils/git/Git.ts b/src/lib/server/utils/git/Git.ts index e91a9ca..9ada0a5 100644 --- a/src/lib/server/utils/git/Git.ts +++ b/src/lib/server/utils/git/Git.ts @@ -19,6 +19,7 @@ export class Git { // Repo commands fetch = () => repo.fetch(this.repoPath); + fetchTags = () => repo.fetchTags(this.repoPath); pull = () => repo.pull(this.repoPath); push = () => repo.push(this.repoPath); checkout = (branch: string) => repo.checkout(this.repoPath, branch); diff --git a/src/lib/server/utils/git/repo.ts b/src/lib/server/utils/git/repo.ts index b1be2ba..938423f 100644 --- a/src/lib/server/utils/git/repo.ts +++ b/src/lib/server/utils/git/repo.ts @@ -125,6 +125,13 @@ export async function fetch(repoPath: string): Promise { await execGitSafe(['fetch', '--quiet'], repoPath); } +/** + * Fetch tags from remote + */ +export async function fetchTags(repoPath: string): Promise { + await execGitSafe(['fetch', '--tags', '--quiet'], repoPath); +} + /** * Pull from remote */ diff --git a/src/routes/api/arr/[id]/library/+server.ts b/src/routes/api/arr/[id]/library/+server.ts index 2aadecc..7e12331 100644 --- a/src/routes/api/arr/[id]/library/+server.ts +++ b/src/routes/api/arr/[id]/library/+server.ts @@ -1,7 +1,7 @@ import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { arrInstancesQueries } from '$db/queries/arrInstances.ts'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; import { cache } from '$cache/cache.ts'; import { RadarrClient } from '$utils/arr/clients/radarr.ts'; diff --git a/src/routes/api/databases/+server.ts b/src/routes/api/databases/+server.ts index f431e1b..6a37c4b 100644 --- a/src/routes/api/databases/+server.ts +++ b/src/routes/api/databases/+server.ts @@ -1,6 +1,6 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; /** * GET /api/databases diff --git a/src/routes/api/v1/entity-testing/evaluate/+server.ts b/src/routes/api/v1/entity-testing/evaluate/+server.ts index 6687d4d..424f600 100644 --- a/src/routes/api/v1/entity-testing/evaluate/+server.ts +++ b/src/routes/api/v1/entity-testing/evaluate/+server.ts @@ -5,7 +5,7 @@ import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { parseWithCacheBatch, isParserHealthy, diff --git a/src/routes/api/v1/health/+server.ts b/src/routes/api/v1/health/+server.ts index 8579b53..c194bf3 100644 --- a/src/routes/api/v1/health/+server.ts +++ b/src/routes/api/v1/health/+server.ts @@ -6,7 +6,7 @@ import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { jobsQueries } from '$db/queries/jobs.ts'; import { backupSettingsQueries } from '$db/queries/backupSettings.ts'; import { appInfoQueries } from '$db/queries/appInfo.ts'; -import { getCache } from '$pcd/cache.ts'; +import { getCache } from '$pcd/index.ts'; import { config } from '$config'; type ComponentStatus = 'healthy' | 'degraded' | 'unhealthy'; diff --git a/src/routes/arr/[id]/sync/+page.server.ts b/src/routes/arr/[id]/sync/+page.server.ts index 9aa5f92..debfcf9 100644 --- a/src/routes/arr/[id]/sync/+page.server.ts +++ b/src/routes/arr/[id]/sync/+page.server.ts @@ -2,7 +2,7 @@ import { error, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; import { arrInstancesQueries } from '$db/queries/arrInstances.ts'; import { arrSyncQueries, type SyncTrigger, type ProfileSelection } from '$db/queries/arrSync.ts'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; import * as delayProfileQueries from '$pcd/entities/delayProfiles/index.ts'; diff --git a/src/routes/custom-formats/+page.server.ts b/src/routes/custom-formats/+page.server.ts index 0d7e877..a3e8d47 100644 --- a/src/routes/custom-formats/+page.server.ts +++ b/src/routes/custom-formats/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = () => { // Get all databases diff --git a/src/routes/custom-formats/[databaseId]/+page.server.ts b/src/routes/custom-formats/[databaseId]/+page.server.ts index 4c85228..ba6c635 100644 --- a/src/routes/custom-formats/[databaseId]/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/custom-formats/[databaseId]/[id]/conditions/+page.server.ts b/src/routes/custom-formats/[databaseId]/[id]/conditions/+page.server.ts index f9b152e..60d55b3 100644 --- a/src/routes/custom-formats/[databaseId]/[id]/conditions/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/[id]/conditions/+page.server.ts @@ -1,11 +1,11 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; import * as regularExpressionQueries from '$pcd/entities/regularExpressions/index.ts'; import { getLanguagesWithSupport } from '$lib/server/sync/mappings.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { ConditionData } from '$shared/pcd/display.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/custom-formats/[databaseId]/[id]/general/+page.server.ts b/src/routes/custom-formats/[databaseId]/[id]/general/+page.server.ts index 6b1dde2..e4c3dd9 100644 --- a/src/routes/custom-formats/[databaseId]/[id]/general/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/[id]/general/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = async ({ params }) => { const { databaseId, id } = params; diff --git a/src/routes/custom-formats/[databaseId]/[id]/testing/+page.server.ts b/src/routes/custom-formats/[databaseId]/[id]/testing/+page.server.ts index 6f15db3..8e43d93 100644 --- a/src/routes/custom-formats/[databaseId]/[id]/testing/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/[id]/testing/+page.server.ts @@ -1,7 +1,7 @@ import { error, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase, type OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase, type OperationLayer } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; import type { ConditionResult, ParsedInfo } from '$shared/pcd/display.ts'; import { parse, isParserHealthy } from '$lib/server/utils/arr/parser/client.ts'; diff --git a/src/routes/custom-formats/[databaseId]/[id]/testing/[testId]/+page.server.ts b/src/routes/custom-formats/[databaseId]/[id]/testing/[testId]/+page.server.ts index 1f4432f..d3d05f8 100644 --- a/src/routes/custom-formats/[databaseId]/[id]/testing/[testId]/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/[id]/testing/[testId]/+page.server.ts @@ -1,7 +1,7 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase, type OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase, type OperationLayer } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; export const load: ServerLoad = async ({ params, url }) => { diff --git a/src/routes/custom-formats/[databaseId]/[id]/testing/new/+page.server.ts b/src/routes/custom-formats/[databaseId]/[id]/testing/new/+page.server.ts index 880c553..75187d2 100644 --- a/src/routes/custom-formats/[databaseId]/[id]/testing/new/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/[id]/testing/new/+page.server.ts @@ -1,7 +1,7 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase, type OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase, type OperationLayer } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/custom-formats/[databaseId]/new/+page.server.ts b/src/routes/custom-formats/[databaseId]/new/+page.server.ts index 1f31856..118f7ee 100644 --- a/src/routes/custom-formats/[databaseId]/new/+page.server.ts +++ b/src/routes/custom-formats/[databaseId]/new/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as customFormatQueries from '$pcd/entities/customFormats/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = ({ params }) => { const { databaseId } = params; diff --git a/src/routes/databases/+page.server.ts b/src/routes/databases/+page.server.ts index 1298b19..4bc4d40 100644 --- a/src/routes/databases/+page.server.ts +++ b/src/routes/databases/+page.server.ts @@ -1,6 +1,6 @@ import { fail, redirect } from '@sveltejs/kit'; import type { Actions, ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; export const load: ServerLoad = () => { diff --git a/src/routes/databases/[id]/changes/+page.server.ts b/src/routes/databases/[id]/changes/+page.server.ts index ce3bec7..9f47994 100644 --- a/src/routes/databases/[id]/changes/+page.server.ts +++ b/src/routes/databases/[id]/changes/+page.server.ts @@ -2,8 +2,7 @@ import type { PageServerLoad, Actions } from './$types'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { Git } from '$utils/git/index.ts'; import { logger } from '$logger/logger.ts'; -import { compile, startWatch } from '$lib/server/pcd/cache.ts'; -import { pcdManager } from '$pcd/pcd.ts'; +import { compile, pcdManager } from '$pcd/index.ts'; export const load: PageServerLoad = async ({ parent }) => { const { database } = await parent(); @@ -32,11 +31,10 @@ export const actions: Actions = { const git = new Git(database.local_path); await git.discardOps(files); - // Recompile cache directly instead of relying on file watcher + // Recompile cache after discarding changes if (database.enabled) { try { await compile(database.local_path, id); - await startWatch(database.local_path, id); } catch (err) { await logger.error('Failed to recompile cache after discard', { source: 'changes', diff --git a/src/routes/databases/[id]/config/+page.server.ts b/src/routes/databases/[id]/config/+page.server.ts index 366d37b..a218cf0 100644 --- a/src/routes/databases/[id]/config/+page.server.ts +++ b/src/routes/databases/[id]/config/+page.server.ts @@ -4,9 +4,10 @@ import { readManifest, writeManifest, validateManifest, + readReadme, + writeReadme, type Manifest -} from '$lib/server/pcd/manifest.ts'; -import { readReadme, writeReadme } from '$lib/server/pcd/readme.ts'; +} from '$pcd/index.ts'; import { parseMarkdown } from '$utils/markdown/markdown.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; diff --git a/src/routes/databases/[id]/settings/+page.server.ts b/src/routes/databases/[id]/settings/+page.server.ts index ab45178..99e41d3 100644 --- a/src/routes/databases/[id]/settings/+page.server.ts +++ b/src/routes/databases/[id]/settings/+page.server.ts @@ -1,7 +1,7 @@ import { redirect, fail } from '@sveltejs/kit'; import type { Actions } from '@sveltejs/kit'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; export const actions: Actions = { diff --git a/src/routes/databases/new/+page.server.ts b/src/routes/databases/new/+page.server.ts index 4a6e80e..e44f320 100644 --- a/src/routes/databases/new/+page.server.ts +++ b/src/routes/databases/new/+page.server.ts @@ -1,6 +1,6 @@ import { fail, redirect } from '@sveltejs/kit'; import type { Actions, ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/routes/delay-profiles/+page.server.ts b/src/routes/delay-profiles/+page.server.ts index 57fab78..a8b8596 100644 --- a/src/routes/delay-profiles/+page.server.ts +++ b/src/routes/delay-profiles/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = () => { // Get all databases diff --git a/src/routes/delay-profiles/[databaseId]/+page.server.ts b/src/routes/delay-profiles/[databaseId]/+page.server.ts index 8c6c2e5..076c48f 100644 --- a/src/routes/delay-profiles/[databaseId]/+page.server.ts +++ b/src/routes/delay-profiles/[databaseId]/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import * as delayProfileQueries from '$pcd/entities/delayProfiles/index.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/delay-profiles/[databaseId]/[id]/+page.server.ts b/src/routes/delay-profiles/[databaseId]/[id]/+page.server.ts index 4482a24..28e82b5 100644 --- a/src/routes/delay-profiles/[databaseId]/[id]/+page.server.ts +++ b/src/routes/delay-profiles/[databaseId]/[id]/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as delayProfileQueries from '$pcd/entities/delayProfiles/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { PreferredProtocol } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/routes/delay-profiles/[databaseId]/new/+page.server.ts b/src/routes/delay-profiles/[databaseId]/new/+page.server.ts index 8e5ed29..648d93e 100644 --- a/src/routes/delay-profiles/[databaseId]/new/+page.server.ts +++ b/src/routes/delay-profiles/[databaseId]/new/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as delayProfileQueries from '$pcd/entities/delayProfiles/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { PreferredProtocol } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; diff --git a/src/routes/media-management/+page.server.ts b/src/routes/media-management/+page.server.ts index d02941a..3f90c61 100644 --- a/src/routes/media-management/+page.server.ts +++ b/src/routes/media-management/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = ({ url }) => { // Get all databases diff --git a/src/routes/media-management/[databaseId]/+layout.server.ts b/src/routes/media-management/[databaseId]/+layout.server.ts index b6e4eff..978cfc9 100644 --- a/src/routes/media-management/[databaseId]/+layout.server.ts +++ b/src/routes/media-management/[databaseId]/+layout.server.ts @@ -1,7 +1,7 @@ import { error } from '@sveltejs/kit'; import type { LayoutServerLoad } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; export const load: LayoutServerLoad = async ({ params }) => { const { databaseId } = params; diff --git a/src/routes/media-management/[databaseId]/media-settings/+page.server.ts b/src/routes/media-management/[databaseId]/media-settings/+page.server.ts index f1769b5..98b4d92 100644 --- a/src/routes/media-management/[databaseId]/media-settings/+page.server.ts +++ b/src/routes/media-management/[databaseId]/media-settings/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { list } from '$pcd/entities/mediaManagement/media-settings/read.ts'; export const load: PageServerLoad = async ({ params }) => { diff --git a/src/routes/media-management/[databaseId]/media-settings/new/+page.server.ts b/src/routes/media-management/[databaseId]/media-settings/new/+page.server.ts index 7c5aa08..03b1011 100644 --- a/src/routes/media-management/[databaseId]/media-settings/new/+page.server.ts +++ b/src/routes/media-management/[databaseId]/media-settings/new/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { ArrType } from '$shared/pcd/types.ts'; import type { PropersRepacks } from '$shared/pcd/mediaManagement.ts'; import { createRadarrMediaSettings, createSonarrMediaSettings } from '$pcd/entities/mediaManagement/media-settings/index.ts'; diff --git a/src/routes/media-management/[databaseId]/media-settings/radarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/media-settings/radarr/[name]/+page.server.ts index 3f0d58a..274180f 100644 --- a/src/routes/media-management/[databaseId]/media-settings/radarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/media-settings/radarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getRadarrByName, updateRadarrMediaSettings, removeRadarrMediaSettings } from '$pcd/entities/mediaManagement/media-settings/index.ts'; import type { PropersRepacks } from '$shared/pcd/mediaManagement.ts'; diff --git a/src/routes/media-management/[databaseId]/media-settings/sonarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/media-settings/sonarr/[name]/+page.server.ts index 14da81f..dbd2d93 100644 --- a/src/routes/media-management/[databaseId]/media-settings/sonarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/media-settings/sonarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getSonarrByName, updateSonarrMediaSettings, removeSonarrMediaSettings } from '$pcd/entities/mediaManagement/media-settings/index.ts'; import type { PropersRepacks } from '$shared/pcd/mediaManagement.ts'; diff --git a/src/routes/media-management/[databaseId]/naming/+page.server.ts b/src/routes/media-management/[databaseId]/naming/+page.server.ts index a2b2f25..d868da2 100644 --- a/src/routes/media-management/[databaseId]/naming/+page.server.ts +++ b/src/routes/media-management/[databaseId]/naming/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { list } from '$pcd/entities/mediaManagement/naming/read.ts'; export const load: PageServerLoad = async ({ params }) => { diff --git a/src/routes/media-management/[databaseId]/naming/new/+page.server.ts b/src/routes/media-management/[databaseId]/naming/new/+page.server.ts index d81910b..a54416a 100644 --- a/src/routes/media-management/[databaseId]/naming/new/+page.server.ts +++ b/src/routes/media-management/[databaseId]/naming/new/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { RadarrNamingRow, SonarrNamingRow } from '$shared/pcd/display.ts'; import { createRadarrNaming, createSonarrNaming } from '$pcd/entities/mediaManagement/naming/index.ts'; diff --git a/src/routes/media-management/[databaseId]/naming/radarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/naming/radarr/[name]/+page.server.ts index 33763b6..50cfc4a 100644 --- a/src/routes/media-management/[databaseId]/naming/radarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/naming/radarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getRadarrByName, updateRadarrNaming, removeRadarrNaming } from '$pcd/entities/mediaManagement/naming/index.ts'; import type { RadarrNamingRow } from '$shared/pcd/display.ts'; diff --git a/src/routes/media-management/[databaseId]/naming/sonarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/naming/sonarr/[name]/+page.server.ts index dbc48aa..a6d711b 100644 --- a/src/routes/media-management/[databaseId]/naming/sonarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/naming/sonarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getSonarrByName, updateSonarrNaming, removeSonarrNaming } from '$pcd/entities/mediaManagement/naming/index.ts'; import type { SonarrNamingRow } from '$shared/pcd/display.ts'; diff --git a/src/routes/media-management/[databaseId]/quality-definitions/+page.server.ts b/src/routes/media-management/[databaseId]/quality-definitions/+page.server.ts index 93a1e35..57cbc0d 100644 --- a/src/routes/media-management/[databaseId]/quality-definitions/+page.server.ts +++ b/src/routes/media-management/[databaseId]/quality-definitions/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import { list } from '$pcd/entities/mediaManagement/quality-definitions/read.ts'; export const load: PageServerLoad = async ({ params }) => { diff --git a/src/routes/media-management/[databaseId]/quality-definitions/new/+page.server.ts b/src/routes/media-management/[databaseId]/quality-definitions/new/+page.server.ts index d62ac4f..ba8116c 100644 --- a/src/routes/media-management/[databaseId]/quality-definitions/new/+page.server.ts +++ b/src/routes/media-management/[databaseId]/quality-definitions/new/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import type { ArrType } from '$shared/pcd/types.ts'; import { getAvailableQualities } from '$pcd/entities/mediaManagement/quality-definitions/read.ts'; import { createRadarrQualityDefinitions, createSonarrQualityDefinitions } from '$pcd/entities/mediaManagement/quality-definitions/index.ts'; diff --git a/src/routes/media-management/[databaseId]/quality-definitions/radarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/quality-definitions/radarr/[name]/+page.server.ts index 0db47a7..09988a4 100644 --- a/src/routes/media-management/[databaseId]/quality-definitions/radarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/quality-definitions/radarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getRadarrByName, getAvailableQualities } from '$pcd/entities/mediaManagement/quality-definitions/read.ts'; import { updateRadarrQualityDefinitions, removeRadarrQualityDefinitions } from '$pcd/entities/mediaManagement/quality-definitions/index.ts'; diff --git a/src/routes/media-management/[databaseId]/quality-definitions/sonarr/[name]/+page.server.ts b/src/routes/media-management/[databaseId]/quality-definitions/sonarr/[name]/+page.server.ts index 60f0bb7..537345f 100644 --- a/src/routes/media-management/[databaseId]/quality-definitions/sonarr/[name]/+page.server.ts +++ b/src/routes/media-management/[databaseId]/quality-definitions/sonarr/[name]/+page.server.ts @@ -1,8 +1,8 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { getSonarrByName, getAvailableQualities } from '$pcd/entities/mediaManagement/quality-definitions/read.ts'; import { updateSonarrQualityDefinitions, removeSonarrQualityDefinitions } from '$pcd/entities/mediaManagement/quality-definitions/index.ts'; diff --git a/src/routes/quality-profiles/+page.server.ts b/src/routes/quality-profiles/+page.server.ts index f729633..b0a40e4 100644 --- a/src/routes/quality-profiles/+page.server.ts +++ b/src/routes/quality-profiles/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = () => { // Get all databases diff --git a/src/routes/quality-profiles/[databaseId]/+page.server.ts b/src/routes/quality-profiles/[databaseId]/+page.server.ts index f604769..acdd11e 100644 --- a/src/routes/quality-profiles/[databaseId]/+page.server.ts +++ b/src/routes/quality-profiles/[databaseId]/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/quality-profiles/[databaseId]/[id]/general/+page.server.ts b/src/routes/quality-profiles/[databaseId]/[id]/general/+page.server.ts index d2a56d6..26d92a6 100644 --- a/src/routes/quality-profiles/[databaseId]/[id]/general/+page.server.ts +++ b/src/routes/quality-profiles/[databaseId]/[id]/general/+page.server.ts @@ -1,10 +1,10 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; import { getRadarrLanguages } from '$lib/server/sync/mappings.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = async ({ params }) => { const { databaseId, id } = params; diff --git a/src/routes/quality-profiles/[databaseId]/[id]/qualities/+page.server.ts b/src/routes/quality-profiles/[databaseId]/[id]/qualities/+page.server.ts index 9cebaa2..a8f9c68 100644 --- a/src/routes/quality-profiles/[databaseId]/[id]/qualities/+page.server.ts +++ b/src/routes/quality-profiles/[databaseId]/[id]/qualities/+page.server.ts @@ -1,9 +1,9 @@ import { error, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = async ({ params }) => { const { databaseId, id } = params; diff --git a/src/routes/quality-profiles/[databaseId]/[id]/scoring/+page.server.ts b/src/routes/quality-profiles/[databaseId]/[id]/scoring/+page.server.ts index 5af66d1..ef18a69 100644 --- a/src/routes/quality-profiles/[databaseId]/[id]/scoring/+page.server.ts +++ b/src/routes/quality-profiles/[databaseId]/[id]/scoring/+page.server.ts @@ -1,9 +1,9 @@ import { error, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = async ({ params }) => { const { databaseId, id } = params; diff --git a/src/routes/quality-profiles/[databaseId]/new/+page.server.ts b/src/routes/quality-profiles/[databaseId]/new/+page.server.ts index ab6731f..9327771 100644 --- a/src/routes/quality-profiles/[databaseId]/new/+page.server.ts +++ b/src/routes/quality-profiles/[databaseId]/new/+page.server.ts @@ -1,10 +1,10 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as qualityProfileQueries from '$pcd/entities/qualityProfiles/index.ts'; import { getRadarrLanguages } from '$lib/server/sync/mappings.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; export const load: ServerLoad = ({ params }) => { const { databaseId } = params; diff --git a/src/routes/quality-profiles/entity-testing/+page.server.ts b/src/routes/quality-profiles/entity-testing/+page.server.ts index 7609042..39cb5e8 100644 --- a/src/routes/quality-profiles/entity-testing/+page.server.ts +++ b/src/routes/quality-profiles/entity-testing/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = () => { // Get all databases diff --git a/src/routes/quality-profiles/entity-testing/[databaseId]/+page.server.ts b/src/routes/quality-profiles/entity-testing/[databaseId]/+page.server.ts index 05ffa2f..764d7af 100644 --- a/src/routes/quality-profiles/entity-testing/[databaseId]/+page.server.ts +++ b/src/routes/quality-profiles/entity-testing/[databaseId]/+page.server.ts @@ -1,7 +1,7 @@ import { error, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import { tmdbSettingsQueries } from '$db/queries/tmdbSettings.ts'; import { arrInstancesQueries } from '$db/queries/arrInstances.ts'; import * as entityTestQueries from '$pcd/entities/qualityProfiles/entityTests/index.ts'; diff --git a/src/routes/regular-expressions/+page.server.ts b/src/routes/regular-expressions/+page.server.ts index ab41433..aec9bd6 100644 --- a/src/routes/regular-expressions/+page.server.ts +++ b/src/routes/regular-expressions/+page.server.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; export const load: ServerLoad = () => { // Get all databases diff --git a/src/routes/regular-expressions/[databaseId]/+page.server.ts b/src/routes/regular-expressions/[databaseId]/+page.server.ts index 801583e..f4c85e2 100644 --- a/src/routes/regular-expressions/[databaseId]/+page.server.ts +++ b/src/routes/regular-expressions/[databaseId]/+page.server.ts @@ -1,6 +1,6 @@ import { error } from '@sveltejs/kit'; import type { ServerLoad } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; +import { pcdManager } from '$pcd/index.ts'; import * as regularExpressionQueries from '$pcd/entities/regularExpressions/index.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/regular-expressions/[databaseId]/[id]/+page.server.ts b/src/routes/regular-expressions/[databaseId]/[id]/+page.server.ts index 56c7759..9c65d41 100644 --- a/src/routes/regular-expressions/[databaseId]/[id]/+page.server.ts +++ b/src/routes/regular-expressions/[databaseId]/[id]/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as regularExpressionQueries from '$pcd/entities/regularExpressions/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; export const load: ServerLoad = async ({ params }) => { diff --git a/src/routes/regular-expressions/[databaseId]/new/+page.server.ts b/src/routes/regular-expressions/[databaseId]/new/+page.server.ts index e00e93a..3ef3910 100644 --- a/src/routes/regular-expressions/[databaseId]/new/+page.server.ts +++ b/src/routes/regular-expressions/[databaseId]/new/+page.server.ts @@ -1,9 +1,9 @@ import { error, redirect, fail } from '@sveltejs/kit'; import type { ServerLoad, Actions } from '@sveltejs/kit'; -import { pcdManager } from '$pcd/pcd.ts'; -import { canWriteToBase } from '$pcd/writer.ts'; +import { pcdManager } from '$pcd/index.ts'; +import { canWriteToBase } from '$pcd/index.ts'; import * as regularExpressionQueries from '$pcd/entities/regularExpressions/index.ts'; -import type { OperationLayer } from '$pcd/writer.ts'; +import type { OperationLayer } from '$pcd/index.ts'; import { logger } from '$logger/logger.ts'; export const load: ServerLoad = ({ params, url }) => {