Skip to content

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

bash
pnpm add @media-sdk/core@^0.3.0

Interface

ts
import type {
  MediaClient,
  MediaCapabilities,
  Photo,
  Video,
  SearchParams,
  PaginatedResponse,
  MediaViewEvent,
  MediaDownloadEvent,
  MediaEventMap,
} from "@media-sdk/core";
MethodSignatureDescription
capabilitiesreadonly capabilities?: MediaCapabilitiesOptional 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) => () => voidSubscribe to user-action events
trackView(event: MediaViewEvent) => voidRecord a view (your app calls this)
trackDownload(event: MediaDownloadEvent) => voidRecord a download (your app calls this)

SearchParams fields:

FieldTypeDescription
querystringSearch text (required for search methods)
pagenumber?Page number (default varies by provider)
perPagenumber?Results per page
signalAbortSignal?Cancel in-flight search requests
photoFiltersPhotoSearchFilters?Photo-only filters
videoFiltersVideoSearchFilters?Video-only filters

Provider-neutral usage

ts
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,
});
ts
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:

ts
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 false

Use 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:

UseAvoid (deprecated)
PhotoPexelsPhoto, PexelsPhotoSearchResponse, …
VideoPexelsVideo, PexelsVideoSearchResponse, …
PaginatedResponse<T>Raw API response shapes
PaginationProvider-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)

ts
interface Photo {
  id: number;
  width: number;
  height: number;
  url: string;
  photographer?: string;
  src: {
    original: string;
    large: string;
    medium: string;
    small: string;
  };
}

Video shape (normalized)

ts
interface Video {
  id: number;
  width: number;
  height: number;
  url: string;
  image: string;
  duration: number;
  videoFiles: VideoFile[];
}

What MediaClient does not do

  • Emit events on fetchsearchPhotos, getPhoto, etc. only return data. Call trackView / trackDownload from your UI layer. See Events.
  • Silently drop filters — unsupported filters throw. See Filters.
  • Abstract provider choice — pick PexelsMediaClient or PixabayMediaClient (or implement MediaClient yourself). See Provider comparison.

Built-in implementations

ClientPackage exportDocs
PexelsMediaClient@media-sdk/corePexels guide
PixabayMediaClient@media-sdk/corePixabay guide