{"version":3,"sources":["../../src/storage/manager.ts"],"sourcesContent":["/**\n * Manages multiple storage providers with a unified interface.\n *\n * @remarks\n * This module provides centralized management of storage providers, enabling\n * applications to work with multiple storage backends through a single API.\n * It handles provider registration, default selection, and operation routing.\n *\n * @category Storage\n * @module storage/manager\n */\n\nimport type {\n  StorageProvider,\n  StorageUploadResult,\n  StorageFile,\n  StorageListOptions,\n} from \"../types/storage\";\nimport { StorageError } from \"../types/storage\";\n\n/**\n * Manages multiple storage providers with a unified interface for file operations.\n *\n * @remarks\n * The StorageManager provides a consistent API for uploading, downloading, and managing\n * files across different storage backends including IPFS, Pinata, Google Drive, and\n * server-managed storage. It handles provider registration, default provider selection,\n * and automatic fallback scenarios for robust file operations.\n *\n * Used internally by DataController for encrypted file storage, but can also be used\n * directly for custom storage workflows. Each provider implements the `StorageProvider`\n * interface to ensure consistent behavior across different storage backends.\n *\n * The manager supports provider-specific configurations and features while maintaining\n * a uniform API surface for applications.\n * @example\n * ```typescript\n * import { StorageManager, IPFSStorage, PinataStorage } from '@opendatalabs/vana-sdk';\n *\n * const storage = new StorageManager();\n *\n * // Register multiple providers\n * storage.register('ipfs', new IPFSStorage({\n *   apiEndpoint: 'https://api.pinata.cloud/pinning/pinFileToIPFS'\n * }), true);\n * storage.register('pinata', new PinataStorage({\n *   jwt: 'your-pinata-jwt-token'\n * }));\n *\n * // Upload to default provider\n * const result = await storage.upload(fileBlob, 'myfile.json');\n *\n * // Upload to specific provider\n * const result2 = await storage.upload(fileBlob, 'myfile.json', 'pinata');\n * ```\n * @category Storage\n * @see {@link https://docs.vana.com/developer/vana-sdk-documentation/core-modules/storage-providers | Storage Providers Guide} for configuration details\n */\nexport class StorageManager {\n  private providers: Map<string, StorageProvider> = new Map();\n  private defaultProvider: string | null = null;\n\n  /**\n   * Registers a storage provider with the manager.\n   *\n   * @remarks\n   * This method adds a new storage provider to the manager's registry and optionally\n   * sets it as the default provider for subsequent operations. If no default provider\n   * is currently set, the first registered provider automatically becomes the default.\n   * @param name - Unique identifier for the provider\n   * @param provider - The storage provider instance implementing the `StorageProvider` interface\n   * @param isDefault - Whether this provider should be set as the default (defaults to `false`)\n   * @example\n   * ```typescript\n   * const pinata = new PinataStorage({ jwt: 'your-jwt-token' });\n   * storage.register('pinata', pinata, true); // Set as default\n   *\n   * const ipfs = new IPFSStorage({ apiEndpoint: 'https://...' });\n   * storage.register('ipfs', ipfs); // Not default\n   * ```\n   */\n  register(name: string, provider: StorageProvider, isDefault = false): void {\n    this.providers.set(name, provider);\n\n    if (isDefault || this.defaultProvider === null) {\n      this.defaultProvider = name;\n    }\n  }\n\n  /**\n   * Retrieves a registered storage provider.\n   *\n   * @param name - Provider identifier.\n   *   If not specified, returns the default provider.\n   * @returns The requested storage provider instance\n   *\n   * @throws {StorageError} With code 'NO_PROVIDER' if no provider available\n   * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if named provider doesn't exist\n   *\n   * @example\n   * ```typescript\n   * const provider = storage.getProvider('pinata');\n   * const config = provider.getConfig();\n   * ```\n   */\n  getProvider(name?: string): StorageProvider {\n    const providerName = name ?? this.defaultProvider;\n\n    if (!providerName) {\n      throw new StorageError(\n        \"No storage provider specified and no default provider set\",\n        \"NO_PROVIDER\",\n        \"manager\",\n      );\n    }\n\n    const provider = this.providers.get(providerName);\n    if (!provider) {\n      throw new StorageError(\n        `Storage provider '${providerName}' not found`,\n        \"PROVIDER_NOT_FOUND\",\n        \"manager\",\n      );\n    }\n\n    return provider;\n  }\n\n  /**\n   * Lists all registered provider names.\n   *\n   * @returns Array of registered provider identifiers\n   *\n   * @example\n   * ```typescript\n   * const providers = storage.listProviders();\n   * console.log('Available providers:', providers);\n   * // Output: ['ipfs', 'pinata', 'google-drive']\n   * ```\n   */\n  listProviders(): string[] {\n    return Array.from(this.providers.keys());\n  }\n\n  /**\n   * Gets the current default provider name.\n   *\n   * @returns Default provider identifier or null if none set\n   *\n   * @example\n   * ```typescript\n   * const defaultName = storage.getDefaultProvider();\n   * if (defaultName) {\n   *   console.log(`Using ${defaultName} by default`);\n   * }\n   * ```\n   */\n  getDefaultProvider(): string | null {\n    return this.defaultProvider;\n  }\n\n  /**\n   * Sets the default storage provider.\n   *\n   * @param name - Provider identifier to set as default.\n   *   Must be a registered provider name.\n   *\n   * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if provider not registered\n   *\n   * @example\n   * ```typescript\n   * storage.setDefaultProvider('pinata');\n   * // Now all operations without provider name will use Pinata\n   * ```\n   */\n  setDefaultProvider(name: string): void {\n    if (!this.providers.has(name)) {\n      throw new StorageError(\n        `Cannot set default provider '${name}': provider not registered`,\n        \"PROVIDER_NOT_FOUND\",\n        \"manager\",\n      );\n    }\n    this.defaultProvider = name;\n  }\n\n  /**\n   * Uploads a file using the specified or default storage provider.\n   *\n   * @remarks\n   * This method uploads a file to the specified provider or falls back to the default\n   * provider if none is specified. The upload result includes the storage URL, file size,\n   * content type, and provider-specific metadata that can be used for subsequent operations.\n   * @param file - The file blob to upload\n   * @param filename - Optional custom filename (defaults to auto-generated name)\n   * @param providerName - Optional provider identifier (uses default if not specified)\n   * @returns A Promise that resolves to the storage upload result with URL and metadata\n   * @throws {StorageError} When no provider is available or upload fails\n   * @example\n   * ```typescript\n   * // Upload to default provider\n   * const result = await storage.upload(fileBlob, 'data.json');\n   * console.log(`Uploaded to: ${result.url}`);\n   *\n   * // Upload to specific provider\n   * const result2 = await storage.upload(fileBlob, 'data.json', 'pinata');\n   * ```\n   */\n  async upload(\n    file: Blob,\n    filename?: string,\n    providerName?: string,\n  ): Promise<StorageUploadResult> {\n    const provider = this.getProvider(providerName);\n    return provider.upload(file, filename);\n  }\n\n  /**\n   * Downloads a file from storage.\n   *\n   * @param url - The storage URL to download from.\n   *   Format depends on the storage provider.\n   * @param providerName - Optional provider identifier.\n   *   Uses default provider if not specified.\n   * @returns The downloaded file as a Blob\n   *\n   * @throws {StorageError} If download fails or provider unavailable\n   *\n   * @example\n   * ```typescript\n   * const blob = await storage.download('ipfs://QmXxx...');\n   * const text = await blob.text();\n   * ```\n   */\n  async download(url: string, providerName?: string): Promise<Blob> {\n    const provider = this.getProvider(providerName);\n    return provider.download(url);\n  }\n\n  /**\n   * Lists files in storage.\n   *\n   * @param options - Optional filtering and pagination.\n   * @param options.namePattern - Pattern to filter files.\n   * @param options.limit - Maximum files to return.\n   * @param providerName - Optional provider identifier.\n   *   Uses default provider if not specified.\n   * @returns Array of file metadata\n   *\n   * @throws {StorageError} If listing fails or not supported by provider\n   *\n   * @example\n   * ```typescript\n   * const files = await storage.list(\n   *   { namePattern: '*.json', limit: 10 },\n   *   'google-drive'\n   * );\n   * ```\n   */\n  async list(\n    options?: StorageListOptions,\n    providerName?: string,\n  ): Promise<StorageFile[]> {\n    const provider = this.getProvider(providerName);\n    return provider.list(options);\n  }\n\n  /**\n   * Deletes a file from storage.\n   *\n   * @param url - The storage URL to delete.\n   *   Must be a valid URL for the provider.\n   * @param providerName - Optional provider identifier.\n   *   Uses default provider if not specified.\n   * @returns True if deletion succeeded, false otherwise\n   *\n   * @throws {StorageError} If deletion fails or not supported by provider\n   *\n   * @example\n   * ```typescript\n   * const success = await storage.delete('ipfs://QmXxx...');\n   * if (success) {\n   *   console.log('File deleted successfully');\n   * }\n   * ```\n   */\n  async delete(url: string, providerName?: string): Promise<boolean> {\n    const provider = this.getProvider(providerName);\n    return provider.delete(url);\n  }\n\n  /**\n   * Gets all registered storage provider names.\n   *\n   * @returns Array of provider identifiers\n   *\n   * @deprecated Use `listProviders()` instead\n   *\n   * @example\n   * ```typescript\n   * const providers = storage.getStorageProviders();\n   * ```\n   */\n  getStorageProviders(): string[] {\n    return Array.from(this.providers.keys());\n  }\n\n  /**\n   * Gets the default storage provider name.\n   *\n   * @returns Default provider identifier or undefined if none set\n   *\n   * @deprecated Use `getDefaultProvider()` instead\n   *\n   * @example\n   * ```typescript\n   * const defaultProvider = storage.getDefaultStorageProvider();\n   * ```\n   */\n  getDefaultStorageProvider(): string | undefined {\n    return this.defaultProvider ?? undefined;\n  }\n}\n"],"mappings":"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","names":[]}