Geert Rademakes 218046ec4f webdav setup
2025-09-17 10:55:35 +02:00

144 lines
3.6 KiB
TypeScript

/**
* Storage Provider Interface
*
* This interface defines the contract that all storage providers (S3, WebDAV, etc.)
* must implement to ensure consistent behavior across different storage backends.
*/
export interface StorageConfig {
provider: 's3' | 'webdav';
[key: string]: any; // Allow additional provider-specific config
}
export interface UploadResult {
key: string;
url: string;
size: number;
contentType: string;
}
export interface FileInfo {
key: string;
size: number;
lastModified: Date;
contentType?: string;
}
export interface StorageProvider {
/**
* Upload a file to storage
*/
uploadFile(
file: Buffer,
originalName: string,
contentType: string,
targetFolder?: string
): Promise<UploadResult>;
/**
* List all files in storage
*/
listAllFiles(prefix?: string): Promise<FileInfo[]>;
/**
* List all folders in storage
*/
listAllFolders(prefix?: string): Promise<string[]>;
/**
* Generate a presigned/secure URL for file access
*/
getPresignedUrl(key: string, expiresIn?: number): Promise<string>;
/**
* Delete a file from storage
*/
deleteFile(key: string): Promise<void>;
/**
* Check if a file exists
*/
fileExists(key: string): Promise<boolean>;
/**
* Get file metadata
*/
getFileMetadata(key: string): Promise<any>;
/**
* Get file content as buffer
*/
getFileContent(key: string): Promise<Buffer>;
/**
* Get streaming URL for a file
*/
getStreamingUrl(key: string): Promise<string>;
/**
* Test the connection to the storage provider
*/
testConnection(): Promise<boolean>;
}
/**
* Storage Provider Factory
* Creates the appropriate storage provider based on configuration
*/
export class StorageProviderFactory {
static async createProvider(config: StorageConfig): Promise<StorageProvider> {
switch (config.provider) {
case 's3':
const { S3Service } = await import('./s3Service.js');
return new S3Service(config as any);
case 'webdav':
const { WebDAVService } = await import('./webdavService.js');
return new WebDAVService(config as any);
default:
throw new Error(`Unsupported storage provider: ${config.provider}`);
}
}
/**
* Load storage configuration from file or environment
*/
static async loadConfig(): Promise<StorageConfig> {
try {
const configPath = path.join(process.cwd(), 'storage-config.json');
const configData = await fs.readFile(configPath, 'utf-8');
return JSON.parse(configData);
} catch (error) {
console.warn('Failed to load storage-config.json, using environment variables as fallback');
// Determine provider from environment
const provider = process.env.STORAGE_PROVIDER || 's3';
if (provider === 'webdav') {
return {
provider: 'webdav',
url: process.env.WEBDAV_URL || '',
username: process.env.WEBDAV_USERNAME || '',
password: process.env.WEBDAV_PASSWORD || '',
basePath: process.env.WEBDAV_BASE_PATH || '/music-files',
};
} else {
return {
provider: 's3',
endpoint: process.env.S3_ENDPOINT || 'http://localhost:9000',
accessKeyId: process.env.S3_ACCESS_KEY_ID || 'minioadmin',
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || 'minioadmin',
bucketName: process.env.S3_BUCKET_NAME || 'music-files',
region: process.env.S3_REGION || 'us-east-1',
useSSL: process.env.S3_USE_SSL !== 'false',
};
}
}
}
}
// Import required modules
import fs from 'fs/promises';
import path from 'path';