@pixengine/adapter-storage-local
v0.1.1
Published
Local filesystem storage adapter for PixEngine
Downloads
207
Maintainers
Readme
@pixengine/adapter-storage-local
English | 한국어
Local filesystem storage adapter for PixEngine.
Installation
npm install @pixengine/adapter-storage-local
# or
pnpm add @pixengine/adapter-storage-local
# or
yarn add @pixengine/adapter-storage-localUsage
import { optimize } from '@pixengine/core';
import { SharpEngine } from '@pixengine/adapter-engine-sharp';
import { LocalStorage } from '@pixengine/adapter-storage-local';
const manifest = await optimize({
input: {
filename: 'photo.jpg',
bytes: imageBuffer,
contentType: 'image/jpeg',
},
policy: (ctx) => ({
variants: [
{ width: 400, format: 'webp', quality: 80 },
{ width: 800, format: 'webp', quality: 85 },
],
}),
engine: new SharpEngine(),
storage: new LocalStorage({ // ✨ Save to local disk
baseDir: './public/uploads',
baseUrl: 'https://example.com/uploads',
}),
});
console.log(manifest.variants[0].url);
// 'https://example.com/uploads/variants/photo_400w.webp'Features
- 💾 Local Filesystem: Save images directly to disk
- 📁 Automatic Directory Creation: Creates nested directories as needed
- 🔗 URL Generation: Generates public URLs for stored images
- ⚡ Simple & Fast: No external dependencies or services required
API
LocalStorage
Implements the StorageAdapter interface from @pixengine/core.
Constructor
new LocalStorage(config: {
baseDir: string;
baseUrl: string;
})Parameters:
baseDir: string- Root directory for file storage- Example:
'./public/uploads' - Example:
'/var/www/static/images'
- Example:
baseUrl: string- Base URL for accessing stored files- Example:
'https://example.com/uploads' - Example:
'http://localhost:3000/static/images'
- Example:
Methods
put(args)
Save an image to the local filesystem.
const result = await storage.put({
key: 'variants/photo_800w.webp',
bytes: imageBytes,
contentType: 'image/webp',
meta: {
width: 800,
height: 600,
format: 'webp',
},
});
console.log(result);
// { url: 'https://example.com/uploads/variants/photo_800w.webp' }Parameters:
key: string- File path relative tobaseDirbytes: Uint8Array- Image datacontentType: string- MIME typemeta- Image metadata (for future use)
Returns: Promise<{ url: string }>
File Organization
LocalStorage organizes files automatically:
baseDir/
├── original/
│ └── photo.jpg # Original images
└── variants/
├── photo_400w.webp # Generated variants
└── photo_800w.webpExamples
Express.js Integration
import express from 'express';
import { optimize } from '@pixengine/core';
import { SharpEngine } from '@pixengine/adapter-engine-sharp';
import { LocalStorage } from '@pixengine/adapter-storage-local';
import multer from 'multer';
const app = express();
const upload = multer();
app.post('/upload', upload.single('image'), async (req, res) => {
const manifest = await optimize({
input: {
filename: req.file.originalname,
bytes: new Uint8Array(req.file.buffer),
contentType: req.file.mimetype,
},
policy: (ctx) => ({
variants: [
{ width: 400, format: 'webp', quality: 80 },
{ width: 800, format: 'webp', quality: 85 },
],
}),
engine: new SharpEngine(),
storage: new LocalStorage({
baseDir: './public/uploads',
baseUrl: `${req.protocol}://${req.get('host')}/uploads`,
}),
});
res.json(manifest);
});
// Serve static files
app.use('/uploads', express.static('./public/uploads'));
app.listen(3000);Next.js Integration
// app/api/upload/route.ts
import { optimize } from '@pixengine/core';
import { SharpEngine } from '@pixengine/adapter-engine-sharp';
import { LocalStorage } from '@pixengine/adapter-storage-local';
export async function POST(request: Request) {
const formData = await request.formData();
const file = formData.get('image') as File;
const bytes = new Uint8Array(await file.arrayBuffer());
const manifest = await optimize({
input: {
filename: file.name,
bytes,
contentType: file.type,
},
policy: (ctx) => ({
variants: [
{ width: 400, format: 'webp', quality: 80 },
{ width: 800, format: 'webp', quality: 85 },
],
}),
engine: new SharpEngine(),
storage: new LocalStorage({
baseDir: './public/uploads',
baseUrl: '/uploads',
}),
});
return Response.json(manifest);
}Then configure next.config.js to serve static files:
// next.config.js
module.exports = {
// ... other config
};Production Considerations
Security
- Validate file paths: Ensure
baseDiris properly sandboxed - Limit file sizes: Use upload size limits
- Sanitize filenames: Remove special characters
Performance
- Use CDN: Serve files through a CDN for better performance
- Set up caching: Configure proper cache headers
- Consider object storage: For high-scale applications, consider S3-compatible storage
File System
- Disk space: Monitor available disk space
- Backup: Regular backups of the storage directory
- Permissions: Ensure proper file/directory permissions
When to Use
LocalStorage is ideal for:
- ✅ Development and testing
- ✅ Small to medium applications
- ✅ Single-server deployments
- ✅ Applications with predictable storage needs
Consider cloud storage (S3, etc.) for:
- ❌ High-scale applications
- ❌ Multi-server deployments
- ❌ Applications requiring CDN integration
- ❌ Distributed systems
Requirements
- Node.js >= 18.0.0
- Write permissions for
baseDir
License
MIT © PixEngine Team
