npm package: @ralalabs/media-js
Description: Official JavaScript/TypeScript SDK for the Rala Media Core API.
Author: Rala Labs
Latest version: 0.2.6

# Rala Media JS SDK

Official JavaScript/TypeScript SDK for the Rala Media Core API.

A strongly typed JavaScript/TypeScript client designed for both machine-to-machine services and user-authenticated applications.

---

## Features

- Fully typed SDK
- Service client (machine-to-machine, X-API-Key)
- User client (Bearer authentication with automatic refresh on 401)
- Works in Node.js, browsers, workers, and edge runtimes
- ESM + CJS exports
- Zero runtime dependencies

---

## Installation

```bash
pnpm add @ralalabs/media-js
```

---

## Architecture

The SDK supports **three usage styles**, all sharing the same generated API surface.

| Client         | Purpose                                             |
| -------------- | --------------------------------------------------- |
| Service Client | Machine-to-machine integrations                     |
| User Client    | End-user authentication flows                       |
| Unified Client | Automatically selects behavior based on credentials |

All clients expose the same API structure — only authentication differs.

---

## Unified client

Recommended entry point for most consumers.

```ts
import { createClient } from '@ralalabs/media-js';

const api = createClient({
  baseUrl: 'https://api.example.com',
  getApiKey: () => process.env.API_KEY,
});
```

The SDK automatically determines whether the client behaves as a **service client** or **user client** based on the provided options.

---

## Service client

Used for backend services, cron jobs, workers, or internal integrations.

Authentication is performed using **X-API-Key**.

```ts
import { createServiceClient } from '@ralalabs/media-js';

const api = createServiceClient({
  baseUrl: 'https://api.example.com',
  getApiKey: () => process.env.API_KEY,
});

const media = await api.repos.media.list({
  filters: {
    mediaType: 'movie',
    imdbScore: { min: 7.5, max: 9.0 },
    has4k: true,
    subtitleLanguages: ['ro', 'fr'],
    audioLanguages: 'en',
    availableVideoCompression: 'H.265',
  },
  page: 1,
  pageSize: 25,
  sort: { by: 'rank1d', order: 'asc' },
});
```

### Characteristics

- Stateless
- No refresh logic
- Safe for background workers
- Ideal for microservices

---

## User client

Used in applications where users authenticate via login.

Supports:

- Access token
- Refresh token
- Automatic refresh on 401
- Refresh de-duplication

```ts
import { createUserClient } from '@ralalabs/media-js';

let accessToken = 'eyJhbGciOiJIUzI1…';
let refreshToken = 'eyJzdWIiOiJjOTM…';

const mlc = createUserClient({
  baseUrl: 'https://127.0.0.1',

  getAccessToken: () => accessToken,
  getRefreshToken: () => refreshToken,

  onTokens(tokens) {
    accessToken = tokens.accessToken;
    refreshToken = tokens.refreshToken;
  },
});
```

## API structure

### Repositories

```ts
mlc.repos.media;
mlc.repos.episodes;
mlc.repos.trailers;
mlc.repos.images;
mlc.repos.manifests;
mlc.repos.keys;
```

Each repository supports:

- `list()` — data only
- `listRaw()` — full response
- `get()` — data only
- `getRaw()` — full response

---

### Users

```ts
mlc.users.list();
mlc.users.get(id);
mlc.users.create(data);
mlc.users.update(id, data);
mlc.users.remove(id);
```

---

### Authentication

Available on both clients:

```ts
mlc.auth.register();
mlc.auth.login();
mlc.auth.logout();
mlc.auth.refreshTokens();
mlc.auth.forgotPassword();
mlc.auth.resetPassword();
```

---

### Service client management (user only)

```ts
mlc.serviceClients.create();
mlc.serviceClients.list();
mlc.serviceClients.get();
mlc.serviceClients.update();
mlc.serviceClients.disable();

mlc.serviceClients.createKey();
mlc.serviceClients.listKeys();
mlc.serviceClients.revokeKey();
```

---

## Error handling

All SDK errors are normalized into a single error type.

```ts
import { isApiError } from '@ralalabs/media-js';

try {
  await mlc.repos.media.list();
} catch (err) {
  if (isApiError(err)) {
    console.error(err.status);
    console.error(err.backendMessage);
    console.error(err.data);
  }
}
```

### ApiError fields

| Field          | Description                 |
| -------------- | --------------------------- |
| status         | HTTP status                 |
| data           | backend response body       |
| headers        | response headers            |
| backendMessage | best-effort backend message |

---

## Runtime compatibility

| Environment        | Supported |
| ------------------ | --------- |
| Node.js 18+        | ✅        |
| Browsers           | ✅        |
| Cloudflare Workers | ✅        |
| Bun                | ✅        |
| Deno               | ✅        |

The SDK relies only on the standard Fetch API.

---

## Examples

Practical usage examples are available in the repository:

👉 **[View examples →](./examples)**

Examples include:

- Service client usage
- User authentication flows
- Pagination and filtering
- Error handling patterns
- Advanced query usage

---

## License

MIT