@opendatalabs/vana-sdk
Version:
A TypeScript library for interacting with Vana Network smart contracts.
1 lines • 12.9 kB
Source Map (JSON)
{"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":[]}