supa-seed
Version:
A constraint-aware, framework-agnostic database seeding framework with deep PostgreSQL business logic discovery and MakerKit integration support
420 lines โข 21.7 kB
JavaScript
;
/**
* CLI Commands for Storage Integration System
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.StorageCommands = void 0;
const framework_adapter_1 = require("../../features/integration/framework-adapter");
const storage_integration_manager_1 = require("../../features/generation/storage/storage-integration-manager");
const enhanced_supabase_client_1 = require("../../core/utils/enhanced-supabase-client");
const storage_config_1 = require("../../core/config/storage-config");
class StorageCommands {
/**
* Format file size in human readable format
*/
static formatFileSize(bytes) {
if (bytes === 0)
return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
}
/**
* Test storage permissions and connectivity
*/
static async testStorage(options) {
const client = (0, enhanced_supabase_client_1.createEnhancedSupabaseClient)(options.url || process.env.SUPABASE_URL || 'http://127.0.0.1:54321', options.key || process.env.SUPABASE_SERVICE_ROLE_KEY || '');
try {
console.log('๐ Testing storage connectivity and permissions...\n');
// Initialize framework adapter to get proper configuration
const adapter = new framework_adapter_1.FrameworkAdapter(client, undefined, {
debug: options.verbose || false,
frameworkOverride: options.framework
});
await adapter.initialize();
const strategy = adapter.getCurrentStrategy();
// Get storage configuration
const storageConfig = strategy?.getStorageConfig?.() || storage_config_1.StorageConfigUtils.getFrameworkConfig('generic').config;
const bucketName = options.bucket || storageConfig.bucketName || 'media';
console.log('๐ Storage Test Configuration:');
console.log(` Framework: ${strategy?.name || 'generic'}`);
console.log(` Bucket: ${bucketName}`);
console.log(` Domain: ${storageConfig.domain || 'general'}`);
console.log(` RLS Enabled: ${storageConfig.respectRLS ? 'โ
' : 'โ'}`);
// Initialize storage manager
const storageManager = new storage_integration_manager_1.StorageIntegrationManager(client, {
...storageConfig,
bucketName
});
// Test permissions
console.log('\n๐ Testing storage permissions...');
const permissionCheck = await storageManager.checkStoragePermissions(bucketName);
console.log(` Read Access: ${permissionCheck.canRead ? 'โ
' : 'โ'}`);
console.log(` Write Access: ${permissionCheck.canWrite ? 'โ
' : 'โ'}`);
console.log(` Delete Access: ${permissionCheck.canDelete ? 'โ
' : 'โ'}`);
console.log(` Permission Level: ${permissionCheck.permissionLevel}`);
if (permissionCheck.rlsPolicies.length > 0) {
console.log(` RLS Policies: ${permissionCheck.rlsPolicies.length} detected`);
if (options.verbose) {
console.log('\n ๐ RLS Policies:');
permissionCheck.rlsPolicies.forEach(policy => {
console.log(` โข ${policy.name} (${policy.policy_type})`);
});
}
}
if (permissionCheck.restrictions.length > 0) {
console.log('\n โ ๏ธ Restrictions:');
permissionCheck.restrictions.forEach(restriction => {
console.log(` โข ${restriction}`);
});
}
// Test quota
console.log('\n๐ Checking storage quota...');
const quotaInfo = await storageManager.getStorageQuota(bucketName);
console.log(` Current Usage: ${StorageCommands.formatFileSize(quotaInfo.currentUsage)}`);
console.log(` Total Quota: ${StorageCommands.formatFileSize(quotaInfo.totalQuota)}`);
console.log(` Usage Percentage: ${quotaInfo.usagePercentage.toFixed(1)}%`);
console.log(` Files Count: ${quotaInfo.filesCount}`);
console.log(` Near Limit: ${quotaInfo.isNearLimit ? 'โ ๏ธ Yes' : 'โ
No'}`);
// Show recommendations
const allRecommendations = [
...permissionCheck.recommendations,
...quotaInfo.recommendations
];
if (allRecommendations.length > 0) {
console.log('\n๐ก Recommendations:');
[...new Set(allRecommendations)].forEach(rec => {
console.log(` โข ${rec}`);
});
}
console.log('\nโ
Storage test completed');
}
catch (error) {
console.error('โ Storage test failed:', error.message);
if (options.verbose) {
console.error('Debug details:', error);
}
process.exit(1);
}
}
/**
* Generate and upload test media files
*/
static async generateMedia(options) {
const client = (0, enhanced_supabase_client_1.createEnhancedSupabaseClient)(options.url || process.env.SUPABASE_URL || 'http://127.0.0.1:54321', options.key || process.env.SUPABASE_SERVICE_ROLE_KEY || '');
try {
const setupId = options.setupId || `test-setup-${Date.now()}`;
const count = options.count || 3;
console.log(`๐ผ๏ธ Generating ${count} media files for setup: ${setupId}\n`);
// Initialize framework adapter
const adapter = new framework_adapter_1.FrameworkAdapter(client, undefined, {
debug: options.verbose || false,
frameworkOverride: options.framework
});
await adapter.initialize();
const strategy = adapter.getCurrentStrategy();
if (!strategy) {
throw new Error('No strategy available for media generation');
}
// Check if strategy supports storage
if (!strategy.integrateWithStorage) {
throw new Error(`Strategy ${strategy.name} does not support storage integration`);
}
// Prepare custom configuration
const customConfig = {
imagesPerSetup: count
};
if (options.domain) {
customConfig.domain = options.domain;
}
if (options.bucket) {
customConfig.bucketName = options.bucket;
}
if (options.enableRealImages !== undefined) {
customConfig.enableRealImages = options.enableRealImages;
}
console.log('๐ Media Generation Configuration:');
console.log(` Framework: ${strategy.name}`);
console.log(` Setup ID: ${setupId}`);
console.log(` Account ID: ${options.accountId || 'none'}`);
console.log(` Images Count: ${count}`);
console.log(` Real Images: ${customConfig.enableRealImages ? 'โ
' : 'โ'}`);
console.log(` Domain: ${customConfig.domain || 'default'}`);
// Execute storage integration
console.log('\n๐ Starting media generation...');
const result = await strategy.integrateWithStorage(setupId, options.accountId, customConfig);
// Display results
console.log(`\n๐ Media Generation Results:`);
console.log(` Success: ${result.success ? 'โ
' : 'โ'}`);
console.log(` Files Processed: ${result.totalFilesProcessed}`);
console.log(` Files Uploaded: ${result.totalFilesUploaded}`);
console.log(` Total Size: ${StorageCommands.formatFileSize(result.totalSize)}`);
console.log(` Execution Time: ${result.executionTime}ms`);
if (result.mediaAttachments.length > 0) {
console.log(`\n๐ Generated Media Attachments:`);
result.mediaAttachments.forEach((attachment, index) => {
console.log(` ${index + 1}. ${attachment.file_name}`);
console.log(` Type: ${attachment.file_type}`);
console.log(` Size: ${StorageCommands.formatFileSize(attachment.file_size)}`);
console.log(` Path: ${attachment.file_path}`);
if (options.verbose) {
console.log(` Alt Text: ${attachment.alt_text}`);
console.log(` Description: ${attachment.description}`);
}
});
}
if (result.warnings.length > 0) {
console.log('\nโ ๏ธ Warnings:');
result.warnings.forEach(warning => {
console.log(` โข ${warning}`);
});
}
if (result.errors.length > 0) {
console.log('\nโ Errors:');
result.errors.forEach(error => {
console.log(` โข ${error}`);
});
}
if (result.recommendations.length > 0) {
console.log('\n๐ก Recommendations:');
result.recommendations.forEach(rec => {
console.log(` โข ${rec}`);
});
}
console.log('\nโ
Media generation completed');
}
catch (error) {
console.error('โ Media generation failed:', error.message);
if (options.verbose) {
console.error('Debug details:', error);
}
process.exit(1);
}
}
/**
* Show storage configuration for a framework
*/
static async showConfig(options) {
const client = (0, enhanced_supabase_client_1.createEnhancedSupabaseClient)(options.url || process.env.SUPABASE_URL || 'http://127.0.0.1:54321', options.key || process.env.SUPABASE_SERVICE_ROLE_KEY || '');
try {
console.log('โ๏ธ Storage Configuration Analysis\n');
// Initialize framework adapter
const adapter = new framework_adapter_1.FrameworkAdapter(client, undefined, {
debug: options.verbose || false,
frameworkOverride: options.framework
});
await adapter.initialize();
const strategy = adapter.getCurrentStrategy();
const frameworkName = strategy?.name || 'generic';
console.log(`๐ Framework: ${frameworkName}`);
// Get framework-specific storage configuration
const frameworkConfig = storage_config_1.StorageConfigUtils.getFrameworkConfig(frameworkName);
const mergedConfig = storage_config_1.StorageConfigUtils.getMergedConfig(frameworkName);
const envConfig = storage_config_1.StorageConfigUtils.getEnvironmentConfig();
console.log('\n๐๏ธ Framework Storage Configuration:');
console.log(` Bucket Name: ${frameworkConfig.config.bucketName}`);
console.log(` Domain: ${frameworkConfig.config.domain}`);
console.log(` Bucket Strategy: ${frameworkConfig.bucketStrategy}`);
console.log(` Media Strategy: ${frameworkConfig.mediaAttachmentStrategy}`);
console.log(` RLS Respect: ${frameworkConfig.config.respectRLS ? 'โ
' : 'โ'}`);
console.log(` Real Images: ${frameworkConfig.config.enableRealImages ? 'โ
' : 'โ'}`);
console.log(` Images Per Setup: ${frameworkConfig.config.imagesPerSetup}`);
if (frameworkConfig.config.categories) {
console.log(` Categories: ${frameworkConfig.config.categories.join(', ')}`);
}
console.log('\n๐ Environment Configuration:');
console.log(` Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(` Real Images Override: ${envConfig.enableRealImages ? 'โ
' : 'โ'}`);
console.log(` RLS Override: ${envConfig.respectRLS ? 'โ
' : 'โ'}`);
console.log('\n๐ง Default Permissions:');
console.log(` Respect RLS: ${frameworkConfig.defaultPermissions.respectRLS ? 'โ
' : 'โ'}`);
console.log(` Enable Public URLs: ${frameworkConfig.defaultPermissions.enablePublicUrls ? 'โ
' : 'โ'}`);
console.log(` Require Auth: ${frameworkConfig.defaultPermissions.requireAuth ? 'โ
' : 'โ'}`);
// Validate configuration
console.log('\nโ
Configuration Validation:');
const validation = storage_config_1.StorageConfigUtils.validate(mergedConfig);
console.log(` Valid: ${validation.isValid ? 'โ
' : 'โ'}`);
if (validation.errors.length > 0) {
console.log('\nโ Configuration Errors:');
validation.errors.forEach(error => {
console.log(` โข ${error}`);
});
}
if (validation.warnings.length > 0) {
console.log('\nโ ๏ธ Configuration Warnings:');
validation.warnings.forEach(warning => {
console.log(` โข ${warning}`);
});
}
// Get recommendations
const recommendations = storage_config_1.StorageConfigUtils.getRecommendations(frameworkName, mergedConfig);
if (recommendations.length > 0) {
console.log('\n๐ก Recommendations:');
recommendations.forEach(rec => {
console.log(` โข ${rec}`);
});
}
// Show API key status
console.log('\n๐ API Key Status:');
console.log(` Unsplash: ${process.env.UNSPLASH_ACCESS_KEY ? 'โ
Configured' : 'โ Missing'}`);
console.log(` Pixabay: ${process.env.PIXABAY_API_KEY ? 'โ
Configured' : 'โ Missing'}`);
if (options.verbose) {
console.log('\n๐ Full Merged Configuration:');
console.log(JSON.stringify(mergedConfig, null, 2));
}
console.log('\nโ
Configuration analysis completed');
}
catch (error) {
console.error('โ Configuration analysis failed:', error.message);
if (options.verbose) {
console.error('Debug details:', error);
}
process.exit(1);
}
}
/**
* Check media attachments for a setup
*/
static async listMedia(options) {
const client = (0, enhanced_supabase_client_1.createEnhancedSupabaseClient)(options.url || process.env.SUPABASE_URL || 'http://127.0.0.1:54321', options.key || process.env.SUPABASE_SERVICE_ROLE_KEY || '');
try {
console.log('๐ Listing media attachments...\n');
const setupId = options.setupId;
const accountId = options.accountId;
if (!setupId && !accountId) {
console.log('โ ๏ธ Please specify either --setup-id or --account-id to filter results');
return;
}
// Build query
let query = client.from('media_attachments').select('*');
if (setupId) {
query = query.eq('setup_id', setupId);
}
if (accountId) {
query = query.eq('account_id', accountId);
}
query = query.order('created_at', { ascending: false });
const { data: mediaAttachments, error } = await query;
if (error) {
throw new Error(`Failed to fetch media attachments: ${error.message}`);
}
if (!mediaAttachments || mediaAttachments.length === 0) {
console.log('๐ญ No media attachments found');
return;
}
console.log(`๐ Found ${mediaAttachments.length} media attachment(s):`);
mediaAttachments.forEach((attachment, index) => {
console.log(`\n ${index + 1}. ${attachment.file_name}`);
console.log(` ID: ${attachment.id}`);
console.log(` Setup ID: ${attachment.setup_id || 'N/A'}`);
console.log(` Account ID: ${attachment.account_id || 'N/A'}`);
console.log(` Type: ${attachment.file_type}`);
console.log(` Size: ${attachment.file_size} bytes`);
console.log(` Bucket: ${attachment.storage_bucket}`);
console.log(` Path: ${attachment.file_path}`);
console.log(` Status: ${attachment.upload_status}`);
console.log(` Public: ${attachment.is_public ? 'โ
' : 'โ'}`);
console.log(` Created: ${new Date(attachment.created_at).toLocaleString()}`);
if (options.verbose) {
console.log(` Alt Text: ${attachment.alt_text || 'N/A'}`);
console.log(` Description: ${attachment.description || 'N/A'}`);
if (attachment.metadata) {
console.log(` Metadata: ${JSON.stringify(attachment.metadata, null, 8)}`);
}
}
});
console.log('\nโ
Media listing completed');
}
catch (error) {
console.error('โ Media listing failed:', error.message);
if (options.verbose) {
console.error('Debug details:', error);
}
process.exit(1);
}
}
/**
* Clean up media attachments and storage files
*/
static async cleanupMedia(options) {
const client = (0, enhanced_supabase_client_1.createEnhancedSupabaseClient)(options.url || process.env.SUPABASE_URL || 'http://127.0.0.1:54321', options.key || process.env.SUPABASE_SERVICE_ROLE_KEY || '');
try {
console.log('๐งน Cleaning up media attachments and storage files...\n');
const setupId = options.setupId;
const bucketName = options.bucket || 'media';
if (!setupId) {
console.log('โ ๏ธ Please specify --setup-id to target specific media for cleanup');
return;
}
// Get media attachments to clean up
const { data: mediaAttachments, error: queryError } = await client
.from('media_attachments')
.select('*')
.eq('setup_id', setupId);
if (queryError) {
throw new Error(`Failed to fetch media attachments: ${queryError.message}`);
}
if (!mediaAttachments || mediaAttachments.length === 0) {
console.log('๐ญ No media attachments found for cleanup');
return;
}
console.log(`๐ Found ${mediaAttachments.length} media attachment(s) to clean up`);
let deletedFiles = 0;
let deletedRecords = 0;
const errors = [];
// Clean up storage files
console.log('\n๐๏ธ Deleting storage files...');
for (const attachment of mediaAttachments) {
try {
const { error: deleteError } = await client.storage
.from(bucketName)
.remove([attachment.file_path]);
if (deleteError) {
errors.push(`Failed to delete ${attachment.file_path}: ${deleteError.message}`);
}
else {
deletedFiles++;
console.log(` โ
Deleted: ${attachment.file_name}`);
}
}
catch (error) {
errors.push(`Error deleting ${attachment.file_path}: ${error.message}`);
}
}
// Clean up database records
console.log('\n๐๏ธ Deleting database records...');
const { error: deleteRecordsError } = await client
.from('media_attachments')
.delete()
.eq('setup_id', setupId);
if (deleteRecordsError) {
errors.push(`Failed to delete media attachment records: ${deleteRecordsError.message}`);
}
else {
deletedRecords = mediaAttachments.length;
console.log(` โ
Deleted ${deletedRecords} database record(s)`);
}
// Summary
console.log(`\n๐ Cleanup Summary:`);
console.log(` Files Deleted: ${deletedFiles}/${mediaAttachments.length}`);
console.log(` Records Deleted: ${deletedRecords}/${mediaAttachments.length}`);
if (errors.length > 0) {
console.log('\nโ Cleanup Errors:');
errors.forEach(error => {
console.log(` โข ${error}`);
});
}
console.log('\nโ
Media cleanup completed');
}
catch (error) {
console.error('โ Media cleanup failed:', error.message);
if (options.verbose) {
console.error('Debug details:', error);
}
process.exit(1);
}
}
}
exports.StorageCommands = StorageCommands;
//# sourceMappingURL=storage-commands.js.map