npm package: @onlive.ai/calendar
Description: > HTTP client for the Onlive Calendar service. Provides strongly typed methods for querying service availability and time slots.
Latest version: 0.0.21

# @onlive.ai/calendar

> HTTP client for the Onlive Calendar service. Provides strongly typed methods for querying service availability and time slots.

[![npm version](https://img.shields.io/npm/v/@onlive.ai/calendar)](https://www.npmjs.com/package/@onlive.ai/calendar)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue?logo=typescript)](https://www.typescriptlang.org/)
[![License: Proprietary](https://img.shields.io/badge/License-Proprietary-red.svg)](https://onlive.site)

## Features

- **Native TypeScript** — full type inference via Zod schemas
- **Runtime validation** — all inputs validated before any network request
- **ESM + CJS** — compatible with ES modules and CommonJS
- **Fetch API** — no additional HTTP dependencies
- **Two endpoints** — `getAvailability` and `getSlots` with standard and compacted response formats

## Installation

```bash
pnpm add @onlive.ai/calendar
# or
npm install @onlive.ai/calendar
```

**Prerequisites**: Node.js ≥ 18.0.0

## Quick Start

```typescript
import { CalendarClient } from "@onlive.ai/calendar";

const client = new CalendarClient({
  baseUrl: "https://api.example.com",
  organizationId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
});

const availability = await client.getAvailability({
  serviceId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  startDate: "2024-01-01T00:00:00Z",
  endDate: "2024-01-07T00:00:00Z",
});
```

## Package Structure

```
@onlive.ai/calendar/
├── index.js                  # Main entry point (ESM)
├── index.cjs                 # CommonJS entry point
├── index.d.ts                # TypeScript declarations (ESM)
├── index.d.cts               # TypeScript declarations (CJS)
├── client/
│   ├── client.service.js     # Client implementation (ESM)
│   ├── client.service.cjs    # Client implementation (CJS)
│   ├── client.service.d.ts   # Service declarations
│   ├── client.types.js       # Schemas and types (ESM)
│   ├── client.types.cjs      # Schemas and types (CJS)
│   └── client.types.d.ts     # Type declarations
└── package.json
```

### Exports

| Import path | Contents |
|---|---|
| `@onlive.ai/calendar` | `CalendarClient` and all types |
| `@onlive.ai/calendar/client/*` | Direct submodule access |

## API Reference

### `new CalendarClient(options)`

Creates a new client instance. Options are validated against the `ClientOptions` Zod schema on construction.

```typescript
import { CalendarClient } from "@onlive.ai/calendar";
import type { ClientOptions } from "@onlive.ai/calendar";

const client = new CalendarClient({
  baseUrl: "https://api.example.com",
  organizationId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
});
```

**`options` — `ClientOptions`**

| Property | Type | Description |
|---|---|---|
| `baseUrl` | `string` (valid URL) | Base URL of the Onlive Calendar API |
| `organizationId` | `string` (UUID) | Organization identifier sent as `X-Onlive-Organization-Id` on every request |

---

### `client.getAvailability(filter, options?)`

Queries service availability. Sends a `POST` request to `{baseUrl}/templates/availability`.

```typescript
import type { GetAvailabilityFilters, GetAvailabilityOptions } from "@onlive.ai/calendar";

const filter: GetAvailabilityFilters = {
  serviceId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  startDate: "2024-01-01T00:00:00Z",
  endDate: "2024-01-07T00:00:00Z",
};

const options: GetAvailabilityOptions = { format: "standard" };

const result = await client.getAvailability(filter, options);
```

**`filter` — `GetAvailabilityFilters`**

| Property | Type | Required | Description |
|---|---|---|---|
| `serviceId` | `string` (UUID) | Yes | Service to query |
| `startDate` | `string` (ISO datetime with offset) | No | Start of the search window |
| `endDate` | `string` | No | End of the search window |
| `calendarFilters` | `Record<string, any>` | No | Filters applied to primary calendars |
| `relatedCalendarFilters` | `Record<string, any>` | No | Filters applied to related calendars |

**`options` — `GetAvailabilityOptions`**

| Property | Type | Description |
|---|---|---|
| `cache` | `boolean` | Enable or disable response caching |
| `format` | `"standard" \| "compacted"` | Response format |

**Returns** `Promise<AvailabilityResponse | AvailabilityResponseCompacted>`

When `format` is `"standard"` (or omitted), resolves to `AvailabilityResponse` — an array of availability windows:

```typescript
[
  {
    availabilityTime: "2024-01-01T09:00:00Z", // ISO datetime with offset
    owners: ["uuid-owner-1"],                  // Owner UUIDs
    assets: ["uuid-asset-1"],                  // Asset UUIDs
  },
]
```

When `format` is `"compacted"`, resolves to `AvailabilityResponseCompacted`:

```typescript
{
  startTime: 1704067200,            // Unix timestamp (ms)
  deltaTimes: {
    "0": [[3600, 7200], [0, 3600]], // [owner deltas, asset deltas]
  },
  owners: ["uuid-owner-1"],
  assets: ["uuid-asset-1"],
}
```

---

### `client.getSlots(filter)`

Retrieves available booking slots. Sends a `GET` request to `{baseUrl}/availabilities/slots`.

```typescript
import type { GetSlotFilters } from "@onlive.ai/calendar";

const filter: GetSlotFilters = {
  serviceId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  fromDate: "2024-01-01",
  toDate: "2024-01-07",
  timezone: "Europe/Madrid",
  bookingSlots: true,
};

const slots = await client.getSlots(filter);
```

**`filter` — `GetSlotFilters`**

| Property | Type | Default | Description |
|---|---|---|---|
| `fromDate` | `string` (YYYY-MM-DD) | — | Start date |
| `toDate` | `string` (YYYY-MM-DD) | — | End date |
| `serviceId` | `string` (UUID) | — | Service to query |
| `timezone` | `string` (IANA timezone) | — | Timezone for returned slots |
| `bookingSlots` | `boolean` | `false` | Include booking slots |
| `compacted` | `boolean` | `false` | Return compacted format |
| `calendars` | `CalendarQuery[]` | — | Calendar filter criteria |

**`calendars[n]` properties**

| Property | Type | Description |
|---|---|---|
| `id` | `string` (UUID) | Single calendar ID |
| `ids` | `string[]` (UUID[]) | Multiple calendar IDs |
| `excludeIds` | `string[]` (UUID[]) | Calendar IDs to exclude |
| `userGroupId` | `string` (UUID) | Filter by user group |
| `organizationId` | `string` (UUID) | Filter by organization |
| `taxonomies` | `string[]` | Exact taxonomy match |
| `taxonomiesContains` | `string[]` | Partial taxonomy match |
| `search` | `string` | Free-text search |
| `extraFields` | `Record<string, any>` | Additional filter fields |
| `type` | `"agent" \| "asset"` | Calendar type |

**Returns** `Promise<SlotResponse | SlotResponseCompacted>`

`SlotResponse`:

```typescript
{
  dateSlotMap: {
    "2024-01-01T00:00:00Z": [
      { startTime: "09:00", endTime: "10:00", calendars: [1, 2] },
    ],
  },
  calendars: [{ id: "uuid-1", name: "Agent A" }],
}
```

---

## Error Handling

The client throws in two scenarios:

**Validation errors** — Input that fails Zod validation throws a `ZodError` _before_ any network request:

```typescript
import { ZodError } from "zod";

try {
  await client.getAvailability({ serviceId: "not-a-valid-uuid" });
} catch (err) {
  if (err instanceof ZodError) {
    console.error("Validation failed:", err.errors);
  }
}
```

**HTTP errors** — Non-2xx responses throw a plain `Error` with the status code:

```typescript
try {
  const result = await client.getAvailability(filter);
} catch (err) {
  console.error(err.message); // "HTTP error! status: 404"
}
```

---

## Type Reference

All types are exported from `@onlive.ai/calendar`:

```typescript
import type {
  ClientOptions,
  GetAvailabilityFilters,
  GetAvailabilityOptions,
  AvailabilityResponse,
  AvailabilityResponseCompacted,
  GetSlotFilters,
  GetSlotOptions,
  SlotResponse,
  SlotResponseCompacted,
  TimeSlot,
  DateSlotMap,
} from "@onlive.ai/calendar";
```

| Type | Description |
|---|---|
| `ClientOptions` | Constructor configuration |
| `GetAvailabilityFilters` | Filter parameters for `getAvailability` |
| `GetAvailabilityOptions` | Request options for `getAvailability` |
| `AvailabilityResponse` | Standard availability response array |
| `AvailabilityResponseCompacted` | Compacted availability response |
| `GetSlotFilters` | Filter parameters for `getSlots` |
| `GetSlotOptions` | Request options for `getSlots` |
| `SlotResponse` | Standard slot response |
| `SlotResponseCompacted` | Compacted slot response |
| `TimeSlot` | Single time slot `{ startTime, endTime, calendars? }` |
| `DateSlotMap` | Map of ISO datetime string to `TimeSlot[]` |

---

## Source Structure

| File | Description |
|---|---|
| `client/client.types.ts` | Zod schemas and inferred TypeScript types |
| `client/client.service.ts` | `CalendarClient` class implementation |
| `index.ts` | Re-exports `CalendarClient` and all types |

Compiled output is distributed in both ESM (`.js` / `.d.ts`) and CommonJS (`.cjs` / `.d.cts`) formats.

---

## Compatibility

| Runtime | Minimum version |
|---|---|
| Node.js | 18.0.0 |
| TypeScript | 4.5.0 |
| Browsers | Requires native Fetch API |

## Development

```bash
pnpm run build:package   # Build ESM + CJS outputs
pnpm run test            # Run tests with Vitest
pnpm run test:coverage   # Run tests with coverage report
pnpm run clean           # Remove compiled outputs
```