@seaverse/utils-sdk
v0.1.1
Published
SeaVerse Utils SDK - Utility toolkit including file upload, image compression, and more
Readme
@seaverse/utils-sdk
SeaVerse Utils SDK - A utility toolkit including file upload, image compression, and more.
Features
- 📤 File Upload - Two-step upload with presigned URLs, secure and efficient
- 🖼️ Image Compression - Auto compress to 1080p, configurable quality and dimensions
- 📊 Upload Progress - Real-time progress callback with speed and remaining time
- ✅ File Validation - Size and type validation
- ⚡ TypeScript - Complete type definitions
- 🌍 Environment Config - Support for multiple environment switching
Installation
npm install @seaverse/utils-sdk
# or
pnpm add @seaverse/utils-sdkQuick Start
Basic Usage
import { UtilsClient } from '@seaverse/utils-sdk';
// Initialize client
const client = new UtilsClient({
token: 'your-bearer-token',
});
// Upload file
const file = document.querySelector('input[type="file"]').files[0];
const result = await client.uploadFile(file);
console.log('CDN URL:', result.cdnUrl);
console.log('File size:', result.fileSize);
console.log('Compressed:', result.compressed);With Progress Callback
const result = await client.uploadFile(file, {
onProgress: (progress) => {
console.log(`Progress: ${progress.percent}%`);
console.log(`Stage: ${progress.stage}`);
console.log(`Speed: ${progress.speed} bytes/sec`);
console.log(`Remaining time: ${progress.remainingTime} sec`);
},
});Disable Image Compression
const result = await client.uploadFile(file, {
compress: false, // Disable compression
});Custom Compression Config
const client = new UtilsClient({
token: 'your-bearer-token',
compress: {
enabled: true,
maxWidth: 1920, // Custom max width
maxHeight: 1080, // Custom max height
quality: 0.9, // Custom compression quality
},
});API Reference
UtilsClient
Constructor
new UtilsClient(options: UtilsClientOptions)Parameters:
token(string, required): Bearer TokenbaseURL(string, optional): API base URL, defaulthttps://resource.seaverse.aitimeout(number, optional): Request timeout (ms), default 60000compress(CompressionConfig, optional): Image compression config
CompressionConfig:
enabled(boolean): Enable compression, defaulttruemaxWidth(number): Max width, default1080maxHeight(number): Max height, default1080quality(number): Compression quality (0-1), default0.8
uploadFile()
Upload file with automatic compression, validation, and upload flow.
async uploadFile(file: File, options?: UploadOptions): Promise<UploadResult>Parameters:
file: File object to uploadoptions(optional):onProgress: Progress callback functioncompress: Whether to compress (overrides global config)metadata: Custom metadata
Returns:
{
fileName: string // File name
originalFileName: string // Original file name
cdnUrl: string // CDN access URL
objectPath: string // Storage path
fileSize: number // File size (bytes)
originalSize: number // Original size (bytes)
compressed: boolean // Whether compressed
contentType: string // MIME type
duration: number // Upload duration (ms)
expiresAt: string // Expiration time
}Errors:
- Throws
UtilsAPIErroron failure
Example:
try {
const result = await client.uploadFile(file, {
onProgress: (progress) => {
updateProgressBar(progress.percent);
},
});
console.log('Upload successful:', result.cdnUrl);
} catch (error) {
if (error instanceof UtilsAPIError) {
console.error(`Upload failed [${error.code}]: ${error.message}`);
}
}setToken()
Update Bearer Token.
setToken(token: string): voidsetBaseURL()
Update base URL.
setBaseURL(baseURL: string): voidupdateCompressionConfig()
Update compression config.
updateCompressionConfig(config: Partial<CompressionConfig>): voidUtility Functions
validateFile()
Validate file size and type.
import { validateFile } from '@seaverse/utils-sdk';
const result = validateFile(file, {
maxSize: 10 * 1024 * 1024, // 10MB
allowedTypes: ['image/jpeg', 'image/png'],
});
if (!result.valid) {
console.error('Validation failed:', result.errors);
}compressImage()
Manually compress image.
import { compressImage } from '@seaverse/utils-sdk';
const result = await compressImage(file, {
maxWidth: 1920,
maxHeight: 1080,
quality: 0.8,
});
console.log('Compression ratio:', result.compressionRatio);
console.log('Compressed size:', result.compressedSize);formatBytes()
Format bytes to human-readable string.
import { formatBytes } from '@seaverse/utils-sdk';
console.log(formatBytes(1024)); // "1 KB"
console.log(formatBytes(1048576)); // "1 MB"
console.log(formatBytes(1073741824)); // "1 GB"Error Handling
import { UtilsAPIError, ErrorCode } from '@seaverse/utils-sdk';
try {
const result = await client.uploadFile(file);
} catch (error) {
if (error instanceof UtilsAPIError) {
switch (error.code) {
case ErrorCode.FILE_TOO_LARGE:
alert('File too large, please select a file smaller than 100MB');
break;
case ErrorCode.INVALID_FILE_TYPE:
alert('Unsupported file type');
break;
case ErrorCode.NETWORK_ERROR:
alert('Network error, please check your connection');
break;
default:
alert(`Upload failed: ${error.message}`);
}
}
}Error Codes
| Error Code | Description |
|------------|-------------|
| FILE_TOO_LARGE | File size exceeds limit |
| INVALID_FILE_TYPE | Unsupported file type |
| PRESIGNED_URL_FAILED | Failed to get presigned URL |
| UPLOAD_FAILED | Upload failed |
| COMPRESSION_FAILED | Image compression failed |
| NETWORK_ERROR | Network error |
| TIMEOUT | Request timeout |
| VALIDATION_FAILED | File validation failed |
Environment Configuration
The SDK provides predefined environment URLs:
import { UtilsClient, ENVIRONMENT_URLS } from '@seaverse/utils-sdk';
// Production environment (default)
const client = new UtilsClient({
token: prodToken,
// baseURL defaults to 'https://resource.seaverse.ai'
});
// Staging/Test environment
const stagingClient = new UtilsClient({
baseURL: ENVIRONMENT_URLS.STAGING, // 'https://resource.sg.seaverse.dev'
token: stagingToken,
});
// Local development
const localClient = new UtilsClient({
baseURL: ENVIRONMENT_URLS.LOCAL, // 'http://localhost:8003'
token: localToken,
});Available Environment URLs
| Environment | URL | Constant |
|-------------|-----|----------|
| Production | https://resource.seaverse.ai | ENVIRONMENT_URLS.PRODUCTION |
| Staging | https://resource.sg.seaverse.dev | ENVIRONMENT_URLS.STAGING |
| Local | http://localhost:8003 | ENVIRONMENT_URLS.LOCAL |
Integration with Auth SDK
import { SeaVerseBackendAPIClient } from '@seaverse/auth-sdk';
import { UtilsClient } from '@seaverse/utils-sdk';
// 1. Login with Auth SDK
const authClient = new SeaVerseBackendAPIClient({
appId: 'your-app-id',
});
const loginResult = await authClient.login({
email: '[email protected]',
password: 'password',
});
// 2. Initialize Utils SDK with the same token
const utilsClient = new UtilsClient({
token: loginResult.token,
});
// 3. Upload file
const result = await utilsClient.uploadFile(file);Upload Flow
The SDK uses presigned URL two-step upload mode:
1. Get presigned URL
POST /api/v1/resources/presign-upload
→ Returns upload_url and cdn_url
2. Upload to GCS
PUT {upload_url}
→ Direct upload to Google Cloud Storage
3. Return CDN URL
Use cdn_url to access the fileAdvantages:
- ✅ Secure: Token not exposed to third-party storage
- ✅ Efficient: Direct upload to GCS, no backend proxy
- ✅ Reliable: GCS provides high availability guarantee
Image Compression
Compression Strategy
- Max size: 1080×1080 pixels (default config)
- Maintains aspect ratio with auto scaling
- Configurable compression quality (0-1)
- Supports custom max width/height (maxWidth, maxHeight)
Compression Trigger Conditions
Compression only occurs when all conditions are met:
- File is an image type (MIME type starts with
image/) - Compression is enabled (
compress.enabled === true) - Not explicitly disabled in upload options (
options.compress !== false)
Skip Compression
// Method 1: Disable globally
const client = new UtilsClient({
token: 'xxx',
compress: { enabled: false },
});
// Method 2: Disable for single upload
const result = await client.uploadFile(file, {
compress: false,
});FAQ
Q1: How to get token?
A: Get Bearer Token by logging in with @seaverse/auth-sdk
Q2: What file types are supported?
A:
- Images: JPEG, PNG, GIF, WebP
- Documents: PDF, TXT, MD
- Others: Depends on backend configuration
Q3: What's the file size limit?
A:
- Default limit: 100MB
- Can be customized via validation rules
- Images are auto-compressed to reduce transfer size
Q4: How to handle upload failures?
A:
try {
await client.uploadFile(file);
} catch (error) {
if (error instanceof UtilsAPIError) {
// Handle based on error code
if (error.code === ErrorCode.NETWORK_ERROR) {
// Retry logic
}
}
}Q5: Does compression affect image quality?
A:
- Default quality is 0.8, balancing file size and image quality
- Adjustable via
qualityparameter (0-1) - Recommended range: 0.7-0.9
Development
# Install dependencies
pnpm install
# Build
pnpm build
# Development mode
pnpm dev
# Type check
pnpm typecheckLicense
MIT © SeaVerse Team
Changelog
v0.1.0 (2026-01-07)
- 🎉 Initial release
- ✨ Support file upload (presigned URL mode)
- ✨ Support auto image compression (1080p)
- ✨ Support upload progress callback
- ✨ Support file validation
- ✨ Complete TypeScript type definitions
