MediaClient
MediaClient is the provider-neutral contract in @media-sdk/core. Both PexelsMediaClient and PixabayMediaClient implement it. Write application code against MediaClient (or a MediaClient-typed variable) so you can swap providers without rewriting search, pagination, or event logic.
Installation
pnpm add @media-sdk/core@^0.3.0Interface
import type {
MediaClient,
MediaCapabilities,
Photo,
Video,
SearchParams,
PaginatedResponse,
MediaViewEvent,
MediaDownloadEvent,
MediaEventMap,
} from "@media-sdk/core";| Method | Signature | Description |
|---|---|---|
capabilities | readonly capabilities?: MediaCapabilities | Optional static capability flags (present on SDK clients) |
searchPhotos | (params: SearchParams) => Promise<PaginatedResponse<Photo>> | Search photos by query |
searchVideos | (params: SearchParams) => Promise<PaginatedResponse<Video>> | Search videos by query |
getPhoto | (id: number) => Promise<Photo> | Fetch one photo by ID |
getVideo | (id: number) => Promise<Video> | Fetch one video by ID |
getCuratedPhotos | (params?: { page?: number; perPage?: number }) => Promise<PaginatedResponse<Photo>> | Curated feed (Pexels only) |
on | <K>(event: K, listener) => () => void | Subscribe to user-action events |
trackView | (event: MediaViewEvent) => void | Record a view (your app calls this) |
trackDownload | (event: MediaDownloadEvent) => void | Record a download (your app calls this) |
SearchParams fields:
| Field | Type | Description |
|---|---|---|
query | string | Search text (required for search methods) |
page | number? | Page number (default varies by provider) |
perPage | number? | Results per page |
signal | AbortSignal? | Cancel in-flight search requests |
photoFilters | PhotoSearchFilters? | Photo-only filters |
videoFilters | VideoSearchFilters? | Video-only filters |
Provider-neutral usage
import {
ApiKeyProvider,
PexelsMediaClient,
type MediaClient,
} from "@media-sdk/core";
const client: MediaClient = new PexelsMediaClient(
new ApiKeyProvider(process.env.PEXELS_API_KEY!),
);
const { items } = await client.searchPhotos({
query: "sunset",
page: 1,
perPage: 20,
});import {
ApiKeyProvider,
PexelsMediaClient,
PixabayMediaClient,
type MediaClient,
} from "@media-sdk/core";
let client: MediaClient;
function setProvider(provider: "pexels" | "pixabay", key: string) {
const auth = new ApiKeyProvider(key);
client =
provider === "pexels"
? new PexelsMediaClient(auth)
: new PixabayMediaClient(auth);
}
async function search(query: string) {
return client.searchPhotos({ query, page: 1, perPage: 20 });
}Instantiate clients directly. There is no ProviderFactory in v0.3.x.
Capabilities on custom implementations
SDK clients expose readonly capabilities: MediaCapabilities. Custom MediaClient implementations may omit it:
import {
DEFAULT_CAPABILITIES,
getCapabilities,
type MediaClient,
type Photo,
type Video,
type SearchParams,
type PaginatedResponse,
} from "@media-sdk/core";
class StubMediaClient implements MediaClient {
// capabilities omitted — getCapabilities returns all-false fallback
async searchPhotos(
_params: SearchParams,
): Promise<PaginatedResponse<Photo>> {
return {
items: [],
pagination: {
page: 1,
perPage: 20,
hasNext: false,
hasPrevious: false,
},
};
}
// ... implement remaining MediaClient methods
}
const caps = getCapabilities(new StubMediaClient());
// equivalent to DEFAULT_CAPABILITIES — all flags falseUse getCapabilities rather than reading client.capabilities directly so custom clients get a safe fallback.
Domain types: Photo and Video
Prefer normalized domain types over wire-specific Pexels types:
| Use | Avoid (deprecated) |
|---|---|
Photo | PexelsPhoto, PexelsPhotoSearchResponse, … |
Video | PexelsVideo, PexelsVideoSearchResponse, … |
PaginatedResponse<T> | Raw API response shapes |
Pagination | Provider-specific pagination fields |
Pexels wire types are internal to the SDK and are not exported from @media-sdk/core. Use normalized domain types in application code.
Photo shape (normalized)
interface Photo {
id: number;
width: number;
height: number;
url: string;
photographer?: string;
src: {
original: string;
large: string;
medium: string;
small: string;
};
}Video shape (normalized)
interface Video {
id: number;
width: number;
height: number;
url: string;
image: string;
duration: number;
videoFiles: VideoFile[];
}What MediaClient does not do
- Emit events on fetch —
searchPhotos,getPhoto, etc. only return data. CalltrackView/trackDownloadfrom your UI layer. See Events. - Silently drop filters — unsupported filters throw. See Filters.
- Abstract provider choice — pick
PexelsMediaClientorPixabayMediaClient(or implementMediaClientyourself). See Provider comparison.
Built-in implementations
| Client | Package export | Docs |
|---|---|---|
PexelsMediaClient | @media-sdk/core | Pexels guide |
PixabayMediaClient | @media-sdk/core | Pixabay guide |
Related pages
- Capabilities — operation and filter flags
- Filters —
photoFilters/videoFilters - Pagination —
PaginatedResponsenavigation - Errors —
MediaErrortaxonomy