@sproux/media-sdk
v0.1.9
Published
Media URL builder library for Sproux — build image variant URLs, video HLS playlist URLs, and thumbnails from original media URLs.
Downloads
662
Maintainers
Readme
@sproux/media-sdk
Media URL builder library for Sproux — build image variant URLs, video HLS playlist URLs, and thumbnails from object keys using a singleton pattern.
Installation
# npm
npm install @sproux/media-sdk
# pnpm
pnpm add @sproux/media-sdk
# yarn
yarn add @sproux/media-sdkQuick Start
import { SprouxMedia, IMAGE_FORMAT, IMAGE_RESIZE_TYPE } from '@sproux/media-sdk';
// Initialize once (e.g. at app startup)
const media = SprouxMedia.init({ cdnUrl: 'https://cdn.example.com' });
// Build an image variant URL with all options
const imageUrl = media.getImageUrl('avatar/image/usr-1/abc.jpg', {
format: IMAGE_FORMAT.WEBP,
width: 200,
height: 200,
resizeType: IMAGE_RESIZE_TYPE.FIT,
quality: 80,
});
// → "https://cdn.example.com/avatar/image/usr-1/abc-w200-h200-fit-q80.webp"
// Width-only (height auto-scaled)
const widthOnly = media.getImageUrl('avatar/image/usr-1/abc.jpg', {
format: IMAGE_FORMAT.WEBP,
width: 200,
resizeType: IMAGE_RESIZE_TYPE.FIT,
});
// → "https://cdn.example.com/avatar/image/usr-1/abc-w200-fit.webp"
// Height-only (width auto-scaled)
const heightOnly = media.getImageUrl('avatar/image/usr-1/abc.jpg', {
format: IMAGE_FORMAT.WEBP,
height: 300,
resizeType: IMAGE_RESIZE_TYPE.FIT,
});
// → "https://cdn.example.com/avatar/image/usr-1/abc-h300-fit.webp"
// Or with just the object key (no variant transformation)
const originalUrl = media.getImageUrl('avatar/image/usr-1/abc.jpg');
// → "https://cdn.example.com/avatar/image/usr-1/abc.jpg"
// Build a video original URL
const videoUrl = media.getVideoOriginalUrl('gallery/video/usr-1/intro.mp4');
// → "https://cdn.example.com/gallery/video/usr-1/intro.mp4"
// Build a video HLS playlist URL
const hlsUrl = media.getVideoHlsUrl('gallery/video/usr-1/intro.mp4');
// → "https://cdn.example.com/gallery/video/usr-1/intro/playlist.m3u8"
// Build a video thumbnail URL
const thumbUrl = media.getVideoThumbnailUrl('gallery/video/usr-1/intro.mp4');
// → "https://cdn.example.com/gallery/video/usr-1/intro/thumbnail_5_0.jpg"Singleton Usage
import { SprouxMedia, IMAGE_FORMAT, IMAGE_RESIZE_TYPE } from '@sproux/media-sdk';
// Initialize once at startup
SprouxMedia.init({ cdnUrl: 'https://cdn.example.com' });
// Access from anywhere via getInstance()
const media = SprouxMedia.getInstance();
// With variant options (both dimensions)
const url = media.getImageUrl('avatar/image/usr-1/photo.jpg', {
format: IMAGE_FORMAT.WEBP,
width: 400,
height: 300,
resizeType: IMAGE_RESIZE_TYPE.FILL,
});
// Without options — returns the original URL
const original = media.getImageUrl('avatar/image/usr-1/photo.jpg');Calling
getInstance()beforeinit()will throw an error.
API Reference
SprouxMedia.init(config: SprouxMediaConfig): SprouxMedia
Initialize the singleton with CDN configuration. Returns the singleton instance.
const media = SprouxMedia.init({ cdnUrl: 'https://cdn.example.com' });SprouxMedia.getInstance(): SprouxMedia
Returns the existing singleton instance. Throws if init() has not been called.
media.getImageUrl(objectKey: string, options?: ImageUrlOptions): string
Build a CDN URL for an image variant. When options is omitted, returns the original CDN URL for the object key as-is.
objectKey— Object key with format (e.g."avatar/image/usr-1/abc.jpg")options— Optional variant transformation options
import { IMAGE_FORMAT, IMAGE_RESIZE_TYPE } from '@sproux/media-sdk';
// With variant options (both dimensions)
media.getImageUrl('avatar/image/usr-1/photo.jpg', {
format: IMAGE_FORMAT.WEBP,
width: 400,
height: 300,
resizeType: IMAGE_RESIZE_TYPE.FILL,
quality: 85,
});
// → "https://cdn.example.com/avatar/image/usr-1/photo-w400-h300-fill-q85.webp"
// Width-only (height auto-scaled)
media.getImageUrl('avatar/image/usr-1/photo.jpg', {
format: IMAGE_FORMAT.WEBP,
width: 400,
resizeType: IMAGE_RESIZE_TYPE.FIT,
});
// → "https://cdn.example.com/avatar/image/usr-1/photo-w400-fit.webp"
// Height-only (width auto-scaled)
media.getImageUrl('avatar/image/usr-1/photo.jpg', {
format: IMAGE_FORMAT.WEBP,
height: 300,
resizeType: IMAGE_RESIZE_TYPE.FIT,
});
// → "https://cdn.example.com/avatar/image/usr-1/photo-h300-fit.webp"
// Without options — returns the original URL
media.getImageUrl('avatar/image/usr-1/photo.jpg');
// → "https://cdn.example.com/avatar/image/usr-1/photo.jpg"ImageUrlOptions
All fields are optional.
| Property | Type | Required | Description |
| -------------- | ------------------- | ---------- | --------------------------------------------------------------------------- |
| format | ImageFormat | No | Output format (webp, avif, jpeg, png, gif, ico, svg, jpg) |
| width | number | No | Target width in pixels (1–4096) |
| height | number | No | Target height in pixels (1–4096) |
| resizeType | ImageResizeType | No | Resize strategy:fit, fill, force, fill-down, auto |
| quality | number | No | Quality 1–100 |
media.getVideoOriginalUrl(objectKey: string): string
Build the original CDN URL for a video from an object key.
media.getVideoOriginalUrl('gallery/video/usr-1/intro.mp4');
// → "https://cdn.example.com/gallery/video/usr-1/intro.mp4"media.getVideoHlsUrl(objectKey: string): string
Build an HLS playlist URL from an object key (without format).
media.getVideoHlsUrl('gallery/video/usr-1/video');
// → "https://cdn.example.com/gallery/video/usr-1/video/playlist.m3u8"media.getVideoThumbnailUrl(objectKey: string): string
Build a thumbnail URL from an object key (without format).
media.getVideoThumbnailUrl('gallery/video/usr-1/video');
// → "https://cdn.example.com/gallery/video/usr-1/video/thumbnail_5_0.jpg"SprouxMedia.getAssetId(objectKey: string): string | null
Extract the asset ID from an object key. Returns null if the object key format is invalid (less than 4 segments).
Object key format: {asset-type}/{purpose}/{user-id}/{asset-id}.{format}
SprouxMedia.getAssetId('avatar/image/usr-1/abc.jpg');
// → "abc"
SprouxMedia.getAssetId('gallery/video/019b7297-f2da-702f-aaa3-612498436e02/019ca305-abe5-7b31-929b-4a1999aeaca1.mp4');
// → "019ca305-abe5-7b31-929b-4a1999aeaca1"
SprouxMedia.getAssetId('invalid/key');
// → nullEnums
Use the provided enums for type-safe image options:
import { IMAGE_FORMAT, IMAGE_RESIZE_TYPE } from '@sproux/media-sdk';
// IMAGE_FORMAT
IMAGE_FORMAT.WEBP // 'webp'
IMAGE_FORMAT.AVIF // 'avif'
IMAGE_FORMAT.JPEG // 'jpeg'
IMAGE_FORMAT.PNG // 'png'
IMAGE_FORMAT.GIF // 'gif'
IMAGE_FORMAT.ICO // 'ico'
IMAGE_FORMAT.SVG // 'svg'
IMAGE_FORMAT.JPG // 'jpg'
// IMAGE_RESIZE_TYPE
IMAGE_RESIZE_TYPE.FIT // 'fit'
IMAGE_RESIZE_TYPE.FILL // 'fill'
IMAGE_RESIZE_TYPE.FORCE // 'force'
IMAGE_RESIZE_TYPE.FILL_DOWN // 'fill-down'
IMAGE_RESIZE_TYPE.AUTO // 'auto'Types
import type {
ImageFormat, // 'webp' | 'avif' | 'jpeg' | 'png' | 'gif' | 'ico' | 'svg' | 'jpg'
ImageResizeType, // 'fit' | 'fill' | 'force' | 'fill-down' | 'auto'
SprouxMediaConfig, // { cdnUrl: string }
ImageUrlOptions, // { format?, width?, height?, resizeType?, quality? }
} from '@sproux/media-sdk';
ImageFormatandImageResizeTypeare string union types derived from their respective enums. You can use either the enum values (IMAGE_FORMAT.WEBP) or raw strings ('webp').
Helper
buildVariantString(options: ImageUrlOptions): string | null
Build a deterministic variant string from image options. Returns null if no options are provided.
import { buildVariantString } from '@sproux/media-sdk';
const variant = buildVariantString({
width: 200,
height: 200,
resizeType: IMAGE_RESIZE_TYPE.FIT,
quality: 80,
}); // "w200-h200-fit-q80"
// Width-only
buildVariantString({ width: 200, resizeType: IMAGE_RESIZE_TYPE.FIT }); // "w200-fit"
// Height-only
buildVariantString({ height: 300, resizeType: IMAGE_RESIZE_TYPE.FIT }); // "h300-fit"
// Empty options
buildVariantString({}); // nullURL Structure
Image Variant URL
{cdnUrl}/{name}-[w{width}][-h{height}]-{resizeType}[-q{quality}].{format}Examples:
- Both dimensions:
https://cdn.example.com/avatar/image/usr-1/photo-w200-h200-fit-q80.webp - Width-only:
https://cdn.example.com/avatar/image/usr-1/photo-w200-fit.webp - Height-only:
https://cdn.example.com/avatar/image/usr-1/photo-h300-fit.webp
Video Original URL
{cdnUrl}/{objectKey}Video HLS URL
{cdnUrl}/{objectKey}/playlist.m3u8Video Thumbnail URL
{cdnUrl}/{name}/thumbnail_5_0.jpgLicense
MIT
