import { FilesystemInterface, GetFilesystemOptions } from '@happyvertical/files'; import { Asset } from './asset'; import { AssetCollection } from './assets'; /** * Options for storing an asset */ export interface StoreOptions { /** MIME type of the data */ mimeType: string; /** Asset type slug (e.g., 'video', 'audio', 'image', 'reference-image') */ typeSlug?: string; /** * Source asset ID (for derivatives like thumbnails, variants, AI edits). * * Renamed from `parentId` in R3-D — see Asset.sourceAssetId. */ sourceAssetId?: string; /** Asset status slug */ statusSlug?: string; /** Description */ description?: string; /** Original source system for imported/derived assets */ sourceType?: string; /** External id in the source system */ externalId?: string; /** JSON metadata stored on the asset record */ metadata?: string | Record | null; } /** * Provider options for configuring the filesystem backend. * Accepts any @happyvertical/files options or a simple basePath string for local storage. */ export type ProviderOptions = GetFilesystemOptions | string; /** * Asset storage operation currently being resolved. */ export type AssetStorageOperation = 'read' | 'write' | 'delete'; /** * Context passed to an AssetStore resolver. * * Downstream apps can use this hook to route a logical Asset to whichever * storage backend is appropriate for the current operation. */ export interface AssetStorageResolveRequest { operation: AssetStorageOperation; asset: Asset; path: string; sourceUri: string; mimeType?: string; typeSlug?: string; defaultProviderOptions: GetFilesystemOptions; defaultFilesystem: FilesystemInterface; } /** * Resolved storage target for an AssetStore operation. */ export interface AssetStorageResolution { filesystem?: FilesystemInterface; providerOptions?: ProviderOptions; path?: string; sourceUri?: string; } export type AssetStorageResolver = (request: AssetStorageResolveRequest) => AssetStorageResolution | null | undefined | Promise; export interface AssetStoreOptions { resolver?: AssetStorageResolver; } /** * AssetStore manages file storage and Asset record creation. * * Files are stored using @happyvertical/files with the convention: * `{typeSlug}/{assetId}.{ext}` * * @example * ```typescript * import { AssetStore } from '@happyvertical/smrt-assets'; * * // Local storage (backward-compatible) * const store = new AssetStore('dev/data/assets', assetCollection); * await store.initialize(); * * // Provider-agnostic storage * const s3Store = new AssetStore({ type: 's3', bucket: 'my-bucket' }, assetCollection); * await s3Store.initialize(); * * // Store a video buffer * const asset = await store.store('my-video', videoBuffer, { * mimeType: 'video/mp4', * typeSlug: 'video', * }); * * // Read it back * const data = await store.read(asset); * * // Delete it * await store.remove(asset); * ``` */ export declare class AssetStore { private readonly collection; private fs; private readonly fsOptions; private readonly fsCache; private readonly resolver?; constructor(providerOrBasePath: ProviderOptions, collection: AssetCollection, options?: AssetStoreOptions); /** The base path for local storage, or empty string for non-local providers */ get basePath(): string; /** * Initialize the filesystem adapter. * Must be called before any file operations. */ initialize(): Promise; /** * Get the initialized filesystem (throws if not initialized) */ private getFs; private providerCacheKey; private getFilesystemForOptions; /** * Build a sourceUri for the given file path based on the provider type. */ private buildSourceUri; private static buildSourceUriForProvider; private static providerRelativePath; private static requireAssetId; private resolveStorage; private writeAssetData; /** * Write file data for an existing Asset record (no DB record created). * * Use this when you've already created the record (e.g., via a * collection.create()) and only need to persist the file data. * * @param asset - The existing asset to write data for * @param data - File data as a Buffer * @param opts - Storage options (mimeType required) * @returns The sourceUri for the written file */ storeFile(asset: Asset, data: Buffer, opts: { mimeType: string; typeSlug?: string; }): Promise; /** * Write buffer to disk and create an Asset record. * * @param name - Human-readable name for the asset * @param data - File data as a Buffer * @param opts - Storage options (mimeType required) * @returns Created Asset instance */ store(name: string, data: Buffer, opts: StoreOptions): Promise; /** * Store a new version of an existing asset. * * @param asset - The existing asset to version * @param data - File data for the new version * @param opts - Optional overrides for store options * @returns The newly created version Asset */ storeVersion(asset: Asset, data: Buffer, opts?: Partial): Promise; /** * Read file data for a specific version of an asset. * * @param asset - The asset (any version in the chain) * @param version - The version number to read * @returns File data as a Buffer */ readVersion(asset: Asset, version: number): Promise; /** * Read file data from an Asset's sourceUri. * * @param asset - Asset to read data for * @returns File data as a Buffer */ read(asset: Asset): Promise; /** * Read file by asset ID. * * @param id - Asset ID to look up * @returns Object with data Buffer and Asset, or null if not found */ readById(id: string): Promise<{ data: Buffer; asset: Asset; } | null>; /** * Delete file from disk and remove the Asset record. * * @param asset - Asset to remove */ remove(asset: Asset): Promise; /** * Extract filesystem path from a sourceUri. * Handles file://, s3://, and plain paths. * * @param sourceUri - Asset sourceUri (e.g., 'file:///path/to/file.mp4', 's3://bucket/key') * @returns Filesystem path */ static pathFromUri(sourceUri: string): string; } //# sourceMappingURL=asset-store.d.ts.map