mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:21:08 +02:00
- Backend (NestJS): Complete API with accounts, folders, emails, labels, compose, attachments, sync providers (IMAP, Gmail, Outlook), AI features (summarize, smart replies, categorization), and OAuth support - Web (SvelteKit): Full email client UI with Svelte 5 runes, sidebar navigation, email list/detail views, compose modal, and theme support - Mobile (Expo): React Native app with drawer navigation, email list/detail, compose screen, account management, and theme provider - Landing (Astro): Marketing page with features, pricing, FAQ sections using shared-landing-ui components - Storage: Added mail bucket and createMailStorage to shared-storage package - Branding: Added MailLogo component Note: Run `pnpm install` to install new dependencies (mailparser) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
@manacore/shared-storage
S3-compatible object storage client for the Manacore monorepo. Uses MinIO for local development and Hetzner Object Storage in production.
Setup
Local Development
- Start MinIO with Docker:
pnpm docker:up
- Access MinIO Console at http://localhost:9001
- Username:
minioadmin - Password:
minioadmin
- Username:
Pre-created Buckets
The following buckets are automatically created:
| Bucket | Project | Purpose |
|---|---|---|
picture-storage |
Picture | Generated AI images |
chat-storage |
Chat | User file uploads |
manadeck-storage |
ManaDeck | Card/deck assets |
nutriphi-storage |
NutriPhi | Meal photos |
presi-storage |
Presi | Presentation slides |
calendar-storage |
Calendar | Calendar attachments |
contacts-storage |
Contacts | Contact avatars/files |
storage-storage |
Storage | Cloud drive files |
Usage
Basic Usage
import { createPictureStorage, generateUserFileKey, getContentType } from '@manacore/shared-storage';
// Create client for Picture project
const storage = createPictureStorage();
// Upload a file
const key = generateUserFileKey('user-123', 'avatar.png');
const result = await storage.upload(key, imageBuffer, {
contentType: getContentType('avatar.png'),
public: true,
});
console.log(result.url); // http://localhost:9000/picture-storage/users/user-123/uuid.png
// Download a file
const buffer = await storage.download(key);
// Delete a file
await storage.delete(key);
// List files
const files = await storage.list('users/user-123/');
// Generate presigned URLs
const uploadUrl = await storage.getUploadUrl('temp/upload.png', { expiresIn: 3600 });
const downloadUrl = await storage.getDownloadUrl(key, { expiresIn: 3600 });
Custom Configuration
import { createStorageClient, BUCKETS } from '@manacore/shared-storage';
// Override default config
const storage = createStorageClient(BUCKETS.PICTURE, {
endpoint: 'https://fsn1.your-objectstorage.com',
region: 'fsn1',
accessKeyId: process.env.HETZNER_ACCESS_KEY,
secretAccessKey: process.env.HETZNER_SECRET_KEY,
forcePathStyle: false,
});
Available Factory Functions
import {
createPictureStorage,
createChatStorage,
createManaDeckStorage,
createNutriPhiStorage,
createPresiStorage,
createCalendarStorage,
createContactsStorage,
createStorageStorage,
} from '@manacore/shared-storage';
Environment Variables
Local Development (MinIO)
Already configured in .env.development:
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
Production (Hetzner Object Storage)
S3_ENDPOINT=https://fsn1.your-objectstorage.com
S3_REGION=fsn1
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
# Optional: public URLs for CDN access
PICTURE_STORAGE_PUBLIC_URL=https://picture-storage.fsn1.your-objectstorage.com
NUTRIPHI_S3_PUBLIC_URL=https://nutriphi-storage.fsn1.your-objectstorage.com
Utilities
import {
generateFileKey,
generateUserFileKey,
getContentType,
validateFileSize,
validateFileExtension,
IMAGE_EXTENSIONS,
DOCUMENT_EXTENSIONS,
} from '@manacore/shared-storage';
// Generate unique file key
const key = generateFileKey('photo.jpg', 'uploads', '2024');
// => 'uploads/2024/uuid.jpg'
// User-scoped key
const userKey = generateUserFileKey('user-123', 'avatar.png', 'avatars');
// => 'users/user-123/avatars/uuid.png'
// Get MIME type
const contentType = getContentType('image.png'); // => 'image/png'
// Validate file
const isValidSize = validateFileSize(fileSize, 10); // max 10MB
const isValidType = validateFileExtension('photo.jpg', IMAGE_EXTENSIONS);
Docker Commands
# Start all infrastructure (Postgres, Redis, MinIO)
pnpm docker:up
# Start only database services (no MinIO)
pnpm docker:up:db
# View MinIO logs
docker logs manacore-minio
# View bucket init logs
docker logs manacore-minio-init