import { html } from '@design.estate/dees-element'; import type { IS3DataProvider, IS3Object } from './interfaces.js'; import './dees-s3-browser.js'; // Mock in-memory S3 data provider for demo purposes class MockS3DataProvider implements IS3DataProvider { private objects: Map = new Map(); constructor() { const now = new Date().toISOString(); // Seed with sample data this.objects.set('documents/readme.md', { content: btoa('# Welcome\n\nThis is a demo S3 browser.\n'), contentType: 'text/markdown', size: 42, lastModified: now, }); this.objects.set('documents/config.json', { content: btoa('{\n "name": "demo",\n "version": "1.0.0"\n}'), contentType: 'application/json', size: 48, lastModified: now, }); this.objects.set('documents/notes/todo.txt', { content: btoa('Buy milk\nFix bug #42\nDeploy to production'), contentType: 'text/plain', size: 45, lastModified: now, }); this.objects.set('images/logo.png', { content: btoa('fake-png-data'), contentType: 'image/png', size: 24500, lastModified: now, }); this.objects.set('images/banner.jpg', { content: btoa('fake-jpg-data'), contentType: 'image/jpeg', size: 156000, lastModified: now, }); this.objects.set('scripts/deploy.sh', { content: btoa('#!/bin/bash\necho "Deploying..."\n'), contentType: 'text/plain', size: 34, lastModified: now, }); this.objects.set('index.html', { content: btoa('\n\n\n

Hello World

\n\n'), contentType: 'text/html', size: 72, lastModified: now, }); this.objects.set('styles.css', { content: btoa('body { margin: 0; font-family: sans-serif; }'), contentType: 'text/css', size: 44, lastModified: now, }); } async listObjects(bucket: string, prefix?: string, delimiter?: string): Promise<{ objects: IS3Object[]; prefixes: string[] }> { const pfx = prefix || ''; const objects: IS3Object[] = []; const prefixes = new Set(); for (const [key, data] of this.objects) { if (!key.startsWith(pfx)) continue; const rest = key.slice(pfx.length); if (delimiter) { const slashIndex = rest.indexOf(delimiter); if (slashIndex >= 0) { prefixes.add(pfx + rest.slice(0, slashIndex + 1)); } else { objects.push({ key, size: data.size, lastModified: data.lastModified }); } } else { objects.push({ key, size: data.size, lastModified: data.lastModified }); } } return { objects, prefixes: Array.from(prefixes).sort() }; } async getObject(bucket: string, key: string): Promise<{ content: string; contentType: string; size: number; lastModified: string }> { const obj = this.objects.get(key); if (!obj) throw new Error('Not found'); return { ...obj }; } async putObject(bucket: string, key: string, base64Content: string, contentType: string): Promise { this.objects.set(key, { content: base64Content, contentType, size: atob(base64Content).length, lastModified: new Date().toISOString(), }); return true; } async deleteObject(bucket: string, key: string): Promise { return this.objects.delete(key); } async deletePrefix(bucket: string, prefix: string): Promise { for (const key of this.objects.keys()) { if (key.startsWith(prefix)) { this.objects.delete(key); } } return true; } async getObjectUrl(bucket: string, key: string): Promise { const obj = this.objects.get(key); if (!obj) return ''; const blob = new Blob([Uint8Array.from(atob(obj.content), c => c.charCodeAt(0))], { type: obj.contentType }); return URL.createObjectURL(blob); } async moveObject(bucket: string, sourceKey: string, destKey: string): Promise<{ success: boolean; error?: string }> { const obj = this.objects.get(sourceKey); if (!obj) return { success: false, error: 'Source not found' }; this.objects.set(destKey, { ...obj, lastModified: new Date().toISOString() }); this.objects.delete(sourceKey); return { success: true }; } async movePrefix(bucket: string, sourcePrefix: string, destPrefix: string): Promise<{ success: boolean; movedCount?: number; error?: string }> { let count = 0; const toMove = Array.from(this.objects.entries()).filter(([k]) => k.startsWith(sourcePrefix)); for (const [key, data] of toMove) { const newKey = destPrefix + key.slice(sourcePrefix.length); this.objects.set(newKey, { ...data, lastModified: new Date().toISOString() }); this.objects.delete(key); count++; } return { success: true, movedCount: count }; } } export const demoFunc = () => html`
`;