/**
* Object Storage Provider Interface
* This defines the contract that all storage providers must implement.
*/
import type { ProviderType, SourceConfig } from "../types/config.js";
import type {
BucketInfo,
ObjectInfo,
ObjectContent,
ObjectMetadata,
ListObjectsResult,
SearchFilter,
SearchResult,
} from "../types/storage.js";
/**
* Provider configuration options
*/
export interface ProviderConfig {
/** Connection timeout in seconds */
connectionTimeoutSeconds?: number;
/** Enable SSL/TLS */
ssl?: boolean;
/** Path style access (for S3-compatible services) */
pathStyle?: boolean;
}
/**
* List objects options
*/
export interface ListObjectsOptions {
/** Filter prefix */
prefix?: string;
/** Delimiter for hierarchical listing */
delimiter?: string;
/** Maximum keys to return */
maxKeys?: number;
/** Continuation token for pagination */
continuationToken?: string;
}
/**
* Get object options
*/
export interface GetObjectOptions {
/** Maximum size to read (in bytes) */
maxSize?: number;
/** Range start (for partial reads) */
rangeStart?: number;
/** Range end (for partial reads) */
rangeEnd?: number;
}
/**
* Object Storage Provider Interface
* All storage providers must implement this interface
*/
export interface Provider {
/** Provider type identifier */
readonly id: ProviderType;
/** Human-readable provider name */
readonly name: string;
/** Get the source ID for this provider instance */
getId(): string;
/** Create a new instance of this provider (for multi-source support) */
clone(): Provider;
/**
* Connect to the storage service
* @param config Source configuration
*/
connect(config: SourceConfig): Promise<void>;
/**
* Disconnect from the storage service
*/
disconnect(): Promise<void>;
/**
* List all buckets
* @returns Array of bucket information
*/
listBuckets(): Promise<BucketInfo[]>;
/**
* List objects in a bucket
* @param bucket Bucket name
* @param options List options
* @returns List of objects with pagination info
*/
listObjects(bucket: string, options?: ListObjectsOptions): Promise<ListObjectsResult>;
/**
* Get object content
* @param bucket Bucket name
* @param key Object key
* @param options Get options
* @returns Object content
*/
getObject(bucket: string, key: string, options?: GetObjectOptions): Promise<ObjectContent>;
/**
* Get object metadata (HEAD request)
* @param bucket Bucket name
* @param key Object key
* @returns Object metadata
*/
getObjectMetadata(bucket: string, key: string): Promise<ObjectMetadata>;
/**
* Check if a bucket exists
* @param bucket Bucket name
* @returns Whether the bucket exists
*/
bucketExists(bucket: string): Promise<boolean>;
/**
* Check if an object exists
* @param bucket Bucket name
* @param key Object key
* @returns Whether the object exists
*/
objectExists(bucket: string, key: string): Promise<boolean>;
/**
* Search objects in a bucket based on filter criteria
* @param bucket Bucket name
* @param filter Search filter
* @returns Search results
*/
searchObjects(bucket: string, filter: SearchFilter): Promise<SearchResult>;
/**
* Get a sample endpoint for this provider type
*/
getSampleEndpoint(): string;
/**
* Validate if an endpoint is valid for this provider
*/
isValidEndpoint(endpoint: string): boolean;
}
/**
* Registry for available storage providers
*/
export class ProviderRegistry {
private static providers: Map<ProviderType, Provider> = new Map();
/**
* Register a new provider
*/
static register(provider: Provider): void {
ProviderRegistry.providers.set(provider.id, provider);
}
/**
* Get a provider by ID
*/
static getProvider(id: ProviderType): Provider | null {
return ProviderRegistry.providers.get(id) || null;
}
/**
* Get provider for a given source config
*/
static getProviderForSource(source: SourceConfig): Provider | null {
return ProviderRegistry.providers.get(source.type) || null;
}
/**
* Get all available provider IDs
*/
static getAvailableProviders(): ProviderType[] {
return Array.from(ProviderRegistry.providers.keys());
}
/**
* Get sample endpoints for all providers
*/
static getAllSampleEndpoints(): { [key in ProviderType]?: string } {
const samples: { [key in ProviderType]?: string } = {};
for (const [id, provider] of ProviderRegistry.providers.entries()) {
samples[id] = provider.getSampleEndpoint();
}
return samples;
}
}