/** * Bucket Router * * Provider-agnostic routing by CONTENT PURPOSE, not provider type. * Routes to REGISTERED adapters from StorageService, no hardcoding. * * Architecture: * 1. Classify upload by purpose (compliance, media-images, etc.) * 2. Check user's adapter preference for that purpose * 3. Route to available adapter that can handle it * 4. Adapter translates purpose to its bucket naming * 5. Universal paths work across all adapters * * @module @plyaz/storage/core */ import type { UploadParams, BucketRouterConfig, RoutingDecision, RoutingRule } from '@plyaz/types/storage'; import { BUCKET_PURPOSE } from '@plyaz/types/storage'; /** * Bucket Router * Routes storage operations by content purpose to available adapters */ export declare class BucketRouter { private rules; private readonly config; private readonly logger?; private readonly adapterPreferences; private availableAdapters; constructor(config?: BucketRouterConfig); /** * Set available adapters (called by StorageService) */ setAvailableAdapters(adapters: string[]): void; /** * Add routing rule */ addRule(rule: RoutingRule): void; /** * Route upload to appropriate adapter/bucket purpose */ route(params: UploadParams): RoutingDecision | null; /** * Add default routing rules * These are suggestions, not hard requirements */ private addDefaultRules; /** * Get suggested adapter for a purpose * Returns first available adapter from preferences or any available adapter */ getAdapterForPurpose(purpose: BUCKET_PURPOSE): string | null; /** * Set adapter preference for a purpose */ setAdapterPreference(purpose: BUCKET_PURPOSE, adapterName: string): void; /** * Sort rules by priority (highest first) */ private sortRules; /** * Get all routing rules (for debugging) */ getRules(): RoutingRule[]; /** * Get available adapters */ getAvailableAdapters(): string[]; /** * Clear all custom rules */ clearRules(): void; /** * Reset to default rules only */ resetToDefaultRules(): void; /** * Helper: Apply path generation to routing decision */ private applyPathGeneration; } /** * Example Usage: * * // In StorageService initialization: * const router = new BucketRouter({ * enableDefaultRules: true, * adapterPreferences: { * [BUCKET_PURPOSE.COMPLIANCE]: 'cloudflare-r2', // User wants compliance on R2 * [BUCKET_PURPOSE.MediaImages]: 'supabase', // User wants media on Supabase * }, * availableAdapters: ['cloudflare-r2', 'supabase'], // From registered adapters * }); * * // Or let user configure at runtime: * router.setAdapterPreference(BUCKET_PURPOSE.COMPLIANCE, 'my-custom-s3'); * * // Routing decision: * const decision = router.route(uploadParams); * if (decision) { * // Use the suggested adapter * adapter = adapterRegistry.getAdapter(decision.adapterName); * } else { * // Use default adapter selection from registry * adapter = adapterRegistry.selectHealthyAdapter(); * } */