UNPKG

@opendatalabs/vana-sdk

Version:

A TypeScript library for interacting with Vana Network smart contracts.

227 lines 7.28 kB
import { StorageError } from "../../types/storage.js"; class CallbackStorage { /** * Creates a new callback-based storage provider. * * @param callbacks - User-provided storage operation callbacks. * Must include at minimum `upload` and `download` functions. * @throws {Error} If required callbacks are missing */ constructor(callbacks) { this.callbacks = callbacks; if (!callbacks.upload || !callbacks.download) { throw new Error( "CallbackStorage requires both upload and download callbacks" ); } } callbacks; /** * Uploads a file using the user-provided callback. * * @param file - The blob to upload. * Can be any Blob-compatible object including File. * @param filename - Optional filename for the upload. * If not provided, callback may generate a name. * @returns Upload result containing URL and metadata * * @throws {StorageError} With code 'INVALID_UPLOAD_RESULT' if callback returns invalid data * @throws {StorageError} With code 'UPLOAD_ERROR' if upload fails * * @example * ```typescript * const file = new File(['content'], 'data.json'); * const result = await storage.upload(file); * console.log('Uploaded to:', result.url); * ``` */ async upload(file, filename) { try { const result = await this.callbacks.upload(file, filename); if (!result.url || result.url.trim() === "") { throw new StorageError( "Upload callback returned invalid result: missing or empty url", "INVALID_UPLOAD_RESULT", "callback-storage" ); } return result; } catch (error) { if (error instanceof StorageError) { throw error; } throw new StorageError( `Upload failed: ${error instanceof Error ? error.message : String(error)}`, "UPLOAD_ERROR", "callback-storage", { cause: error instanceof Error ? error : void 0 } ); } } /** * Downloads a file using the user-provided callback. * * @param url - The URL or identifier to download. * If `extractIdentifier` callback is provided, it will be used to extract the identifier. * @returns The downloaded file as a Blob * * @throws {StorageError} With code 'INVALID_DOWNLOAD_RESULT' if callback returns non-Blob * @throws {StorageError} With code 'DOWNLOAD_ERROR' if download fails * * @example * ```typescript * const blob = await storage.download('https://storage.example.com/file123'); * const text = await blob.text(); * ``` */ async download(url) { try { const identifier = this.callbacks.extractIdentifier ? this.callbacks.extractIdentifier(url) : url; const blob = await this.callbacks.download(identifier); if (!(blob instanceof Blob)) { throw new StorageError( "Download callback returned invalid result: expected Blob", "INVALID_DOWNLOAD_RESULT", "callback-storage" ); } return blob; } catch (error) { if (error instanceof StorageError) { throw error; } throw new StorageError( `Download failed: ${error instanceof Error ? error.message : String(error)}`, "DOWNLOAD_ERROR", "callback-storage", { cause: error instanceof Error ? error : void 0 } ); } } /** * Lists files using the user-provided callback. * * @param options - Optional list options. * @param options.namePattern - Pattern to filter files by name. * Implementation depends on callback. * @param options.limit - Maximum number of files to return. * Implementation depends on callback. * @returns Array of storage file metadata * * @throws {StorageError} With code 'NOT_SUPPORTED' if list callback not provided * @throws {StorageError} With code 'LIST_ERROR' if listing fails * * @remarks * This operation is optional and only available if a `list` callback * is provided during construction. * * @example * ```typescript * const files = await storage.list({ namePattern: '*.json' }); * files.forEach(file => console.log(file.name, file.size)); * ``` */ async list(options) { if (!this.callbacks.list) { throw new StorageError( "List operation not supported - no list callback provided", "NOT_SUPPORTED", "callback-storage" ); } try { const result = await this.callbacks.list(options?.namePattern, options); return result.items.map((item, index) => ({ id: item.identifier, name: item.identifier.split("/").pop() ?? `file-${index}`, url: item.identifier, size: item.size ?? 0, contentType: "application/octet-stream", createdAt: item.lastModified ?? /* @__PURE__ */ new Date(), metadata: item.metadata })); } catch (error) { throw new StorageError( `List failed: ${error instanceof Error ? error.message : String(error)}`, "LIST_ERROR", "callback-storage", { cause: error instanceof Error ? error : void 0 } ); } } /** * Deletes a file using the user-provided callback. * * @param url - The URL or identifier to delete. * If `extractIdentifier` callback is provided, it will be used to extract the identifier. * @returns True if deletion succeeded, false otherwise * * @throws {StorageError} With code 'NOT_SUPPORTED' if delete callback not provided * @throws {StorageError} With code 'DELETE_ERROR' if deletion fails * * @remarks * This operation is optional and only available if a `delete` callback * is provided during construction. * * @example * ```typescript * const deleted = await storage.delete('https://storage.example.com/file123'); * if (deleted) { * console.log('File deleted successfully'); * } * ``` */ async delete(url) { if (!this.callbacks.delete) { throw new StorageError( "Delete operation not supported - no delete callback provided", "NOT_SUPPORTED", "callback-storage" ); } try { const identifier = this.callbacks.extractIdentifier ? this.callbacks.extractIdentifier(url) : url; return await this.callbacks.delete(identifier); } catch (error) { throw new StorageError( `Delete failed: ${error instanceof Error ? error.message : String(error)}`, "DELETE_ERROR", "callback-storage", { cause: error instanceof Error ? error : void 0 } ); } } /** * Returns the provider's configuration and capabilities. * * @returns Configuration object indicating supported features * * @example * ```typescript * const config = storage.getConfig(); * if (config.features.list) { * // List operation is supported * const files = await storage.list(); * } * ``` */ getConfig() { return { name: "callback-storage", type: "callback", requiresAuth: false, features: { upload: true, download: true, list: !!this.callbacks.list, delete: !!this.callbacks.delete } }; } } export { CallbackStorage }; //# sourceMappingURL=callback-storage.js.map