Skip to content

Commit c84dbfb

Browse files
committed
chore: update readme
1 parent 9ef7173 commit c84dbfb

1 file changed

Lines changed: 35 additions & 10 deletions

File tree

README.md

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ A high-performance image processing microservice built with Bun, ElysiaJS, and S
2020
- **OG Image Generation** - Dynamic social media images using Satori (no headless browser)
2121
- **Multiple Templates** - 8 built-in templates + JSON-based custom templates
2222
- **Background Images** - Support for background images with opacity and fit modes (cover, contain, fill, tile)
23-
- **Smart Caching** - Disk, memory, or no caching with CDN-friendly headers
23+
- **Text Watermarks** - Add text watermarks with custom fonts, colors, and positioning
24+
- **Smart Caching** - Disk, memory, Redis, or hybrid caching with CDN-friendly headers
2425
- **SSRF Protection** - Blocks private IPs, localhost, and dangerous protocols
2526
- **Type-Safe** - Full TypeScript with Elysia's TypeBox validation
2627

@@ -104,9 +105,16 @@ Transform remote images with URL parameters.
104105
| `tint` | string | Tint color (hex, e.g., `ff5500`) |
105106
| `trim` | boolean | Trim whitespace |
106107
| `crop` | string | Crop region `x,y,width,height` |
107-
| `watermark` | string | Watermark image URL |
108+
| `size` | number | Percentage resize (1-100) |
109+
| `wm_image` | string | Watermark image URL |
110+
| `wm_text` | string | Watermark text |
108111
| `wm_position` | string | Watermark position (see table below) |
109112
| `wm_opacity` | number | Watermark opacity (0-1) |
113+
| `wm_scale` | number | Watermark scale (1-100) |
114+
| `wm_padding` | number | Watermark padding (0-500) |
115+
| `wm_font` | string | Watermark text font (any Google Font) |
116+
| `wm_fontsize` | number | Watermark text font size (8-200) |
117+
| `wm_color` | string | Watermark text color (hex, e.g., `ff5500`) |
110118

111119
**Position Values** (for `position` and `wm_position`):
112120

@@ -258,7 +266,7 @@ Configure via environment variables:
258266
PORT=3000
259267

260268
# Caching
261-
CACHE_MODE=disk # disk, memory, hybrid, or none
269+
CACHE_MODE=disk # disk, memory, hybrid, redis, or none
262270
CACHE_DIR=./cache
263271
CACHE_TTL=86400 # 24 hours
264272
MAX_CACHE_SIZE=1073741824 # 1GB
@@ -274,6 +282,12 @@ REQUEST_TIMEOUT=30000 # 30 seconds
274282
# Browser/CDN Cache
275283
BROWSER_CACHE_TTL=31536000 # 1 year
276284

285+
# Redis (when CACHE_MODE=redis)
286+
REDIS_URL=redis://localhost:6379
287+
REDIS_KEY_PREFIX=ps:
288+
REDIS_CONNECTION_TIMEOUT=5000
289+
REDIS_MAX_RETRIES=10
290+
277291
# Custom templates
278292
TEMPLATES_DIR=./templates
279293

@@ -288,6 +302,7 @@ CLUSTER_WORKERS=0 # 0 = auto-detect CPU cores
288302
| `disk` | Persist to disk only. Survives restarts but slower reads. |
289303
| `memory` | In-memory LRU cache. Fastest but lost on restart. |
290304
| `hybrid` | Memory (L1) + Disk (L2). Fast reads with persistence. Best for production. |
305+
| `redis` | Redis-backed cache. Best for distributed/multi-instance deployments. |
291306
| `none` | No caching. Every request processes the image fresh. |
292307

293308
### Security Settings
@@ -481,24 +496,33 @@ pixelserve/
481496
│ ├── index.ts # Main server
482497
│ ├── cluster.ts # Multi-process cluster manager
483498
│ ├── config.ts # Environment configuration
499+
│ ├── constants.ts # Named constants (timeouts, limits)
500+
│ ├── middleware/
501+
│ │ ├── origin-validator.ts # Origin/Referer validation guard
502+
│ │ └── error-handler.ts # Shared error handler
484503
│ ├── routes/
485504
│ │ ├── image.ts # Image processing endpoint
486505
│ │ ├── og.ts # OG image generation endpoint
487506
│ │ └── health.ts # Health check
488507
│ ├── services/
489-
│ │ ├── image-processor.ts # Sharp transformations
490-
│ │ ├── image-fetcher.ts # Remote image fetching
491-
│ │ ├── cache.ts # Disk/memory caching
508+
│ │ ├── image-processor.ts # Sharp pipeline orchestrator
509+
│ │ ├── image-fetcher.ts # Remote image fetching with SSRF protection
510+
│ │ ├── cache.ts # Multi-backend caching (disk/memory/hybrid/redis)
492511
│ │ ├── og-generator.ts # Satori + resvg OG generation
493512
│ │ ├── custom-templates.ts # JSON template builder
494-
│ │ └── fonts.ts # Dynamic font loading via Google Fonts
513+
│ │ ├── fonts.ts # Dynamic font loading via Google Fonts
514+
│ │ └── transforms/ # Individual image transform steps
515+
│ │ ├── crop.ts
516+
│ │ ├── resize.ts
517+
│ │ ├── adjustments.ts
518+
│ │ ├── watermark.ts
519+
│ │ └── output.ts
495520
│ ├── utils/
496521
│ │ ├── url-validator.ts # SSRF prevention
497522
│ │ └── errors.ts # Custom error classes
498523
│ └── types/
499524
│ └── index.ts # TypeScript interfaces
500525
├── cache/ # Disk cache (gitignored)
501-
├── fonts/ # Fonts for OG generation
502526
├── templates/ # Custom JSON templates
503527
└── tests/
504528
├── unit/
@@ -507,11 +531,12 @@ pixelserve/
507531

508532
## Security
509533

510-
- **SSRF Prevention**: Blocks `localhost`, `127.0.0.1`, `0.0.0.0`, `::1`, private IP ranges, and `file://` protocol
534+
- **SSRF Prevention**: Blocks `localhost`, `127.0.0.1`, `0.0.0.0`, `::1`, private IP ranges, link-local addresses, and `file://` protocol. Redirects are followed manually with re-validation at each hop.
535+
- **Origin Validation**: Optional `ALLOWED_ORIGINS` blocks requests without a valid Origin/Referer header (subdomain-aware matching)
511536
- **Input Validation**: TypeBox schemas validate all query parameters
512537
- **Size Limits**: Max image dimensions (4096x4096) and file size (10MB)
513538
- **Timeout**: 30-second request timeout prevents hanging connections
514-
- **Domain Allowlist**: Optional `ALLOWED_DOMAINS` to restrict source URLs
539+
- **Domain Allowlist**: Optional `ALLOWED_DOMAINS` to restrict source image URLs
515540

516541
## Performance
517542

0 commit comments

Comments
 (0)