# The rpgdesk.js API

> Every function of the RPG Desk object and the document, with their parameters and what they return.

Page: https://docs.rpgdesk.com/en/referencia/api/

rpgdesk.js creates the global `RPGDesk` object. Almost everything returns a `Promise`: use `await` or `.then()`. Calls made before connecting wait for the connection. To learn with examples, see [JavaScript on the sheet](https://docs.rpgdesk.com/en/fichas/javascript/) and [Rolls, chat and card](https://docs.rpgdesk.com/en/fichas/rolagens-e-chat/).

## RPG Desk

|                         |                                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------- |
| `RPGDesk.connect()`     | connects (to RPG Desk or to test mode) and returns the **context**, with the `doc` |
| `RPGDesk.context`       | the context, once connected (before that, `null`)                                  |
| `RPGDesk.doc`           | the document, once connected (before that, `null`)                                 |
| `RPGDesk.version`       | rpgdesk.js’s version (`'1.0.0'`)                                                   |
| `RPGDesk.on(event, fn)` | listens to a room event; returns the function that stops listening                 |
| `RPGDesk.bind(element)` | connects the `data-…` attributes of a piece of the page built by hand              |

### The context

```ts
{
  kind: 'sheet' | 'table',
  item: { id: string, name: string, type: string, ownerId: string | null },
  me: { id: string, nick: string, role: 'gm' | 'player' | 'spectator', isOwner: boolean },
  room: { id: string, name: string, system: string },
  language: 'pt' | 'en',
  test: boolean,                       // outside RPG Desk, in test mode
  plugin: { id: string, version: string },
  doc: Doc,
}
```

### Events

| Event        | `fn` receives                                       | When                                    |
| ------------ | --------------------------------------------------- | --------------------------------------- |
| `'players'`  | the list of players (like `RPGDesk.room.players()`) | someone joins, leaves or changes        |
| `'library'`  | the library items (like `RPGDesk.room.library()`)   | the library changes                     |
| `'me'`       | the new `me`                                        | the person’s role changes               |
| `'language'` | `'pt'` or `'en'`                                    | the person switches RPG Desk’s language |
| `'theme'`    | the theme variables                                 | the room’s colors change                |

## The document (`doc`)

|                                               |                                                                                                                                                                                                          |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `doc.get(path)`                               | the value: text, number, `true`/`false`, an object (group) or `undefined`. `doc.get('')` gives the whole document                                                                                        |
| `doc.set(path, value)`                        | writes. An object writes field by field; `null` deletes. Returns a promise                                                                                                                               |
| `doc.update({ path: value, … })`              | writes several fields in one batch                                                                                                                                                                       |
| `doc.batch(() => { … })`                      | whatever is written inside the function goes in a single batch, applied whole or refused whole                                                                                                           |
| `doc.watch(path, fn, { now })`                | tells you about each change on the path or inside it: `fn(value, { local })`. Returns the function that stops it                                                                                         |
| `doc.compute(target, [sources], fn)`          | computed field: writes `fn(...source values)` to the target when a source changes in this browser, if the person can write to the target. `undefined` does not write. Returns the function that stops it |
| `doc.canWrite(path)`                          | whether the person can write there                                                                                                                                                                       |
| `doc.list(path)`                              | the list at the path (see below)                                                                                                                                                                         |
| `doc.restrict(path, 'gm' \| 'owner' \| null)` | game masters only: the part becomes game master only, owner and game masters only, or everyone’s again                                                                                                   |
| `doc.on('rejected', fn)`                      | tells you when a write is refused: `fn(message)`. Returns the function that stops it                                                                                                                     |

Paths are texts (`'hp.current'`) or arrays (`['npcs', '#' + id, 'hp']`); `#id` points to a list item.

### Lists

`doc.list(path)` returns:

|                          |                                                                                        |
| ------------------------ | -------------------------------------------------------------------------------------- |
| `items()`                | the items, in order: `[{ id, …fields }]`                                               |
| `length`                 | how many items                                                                         |
| `add(value?, position?)` | creates an item (at the end, or at the position) and returns its `id` right away       |
| `remove(id)`             | deletes the item                                                                       |
| `move(id, position)`     | moves the item                                                                         |
| `item(id)`               | the item: `{ id, get(field), set(field, value), watch(field, fn, { now }), remove() }` |
| `watch(fn, { now })`     | tells you about each change in the list or its items: `fn(items, { local })`           |

## Dice and chat

|                                            |                                                                                                             |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `RPGDesk.dice.roll(expression, { label })` | rolls in the room (with the 3D dice, in everyone’s chat). Returns `{ expression, total, items, successes }` |
| `RPGDesk.chat.send(text, { kind, name })`  | sends to the chat. `kind`: `'chat'`, `'action'`, `'laugh'`, `'narrator'` or `'npc'` (with `name`)           |
| `RPGDesk.chat.local(text)`                 | a line in the chat of whoever is looking only                                                               |

A roll’s `items`: `{ kind: 'dice', sign, faces, results }`, `{ kind: 'fudge', sign, results }` or `{ kind: 'value', sign, value }`. `successes` only exists in rolls with `>`.

## The room and the card

|                                                      |                                                                                                                                                        |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `RPGDesk.room.players()`                             | who is in the room: `[{ id, nick, role, avatar, mainCharacterId }]`                                                                                    |
| `RPGDesk.room.library()`                             | the library items the person sees: `[{ id, name, kind, type, ownerId, parentId }]`                                                                     |
| `RPGDesk.room.on('players' \| 'library', fn)`        | the same as `RPGDesk.on`                                                                                                                               |
| `RPGDesk.card.setBar(index, value, max, { userId })` | the card’s bar: the index goes from 0 (Bar 1) to 3. On a sheet, the card is the owner’s; on a table, pass the `userId`. A maximum of 0 removes the bar |
| `RPGDesk.card.setLine(index, text, { userId })`      | the card’s line: the index goes from 0 to 3; up to 120 characters                                                                                      |

## Interface

|                                         |                                                                                                                                                                    |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `RPGDesk.ui.toast(text, type)`          | a notice. `type`: `'info'`, `'success'` or `'error'`                                                                                                               |
| `RPGDesk.ui.confirm(text, { title })`   | a yes-or-no question: `true` or `false`                                                                                                                            |
| `RPGDesk.ui.prompt(text, initial)`      | asks for a text: the text, or `null` if the person cancels                                                                                                         |
| `RPGDesk.ui.menu(items, where)`         | a RPG Desk menu. `items`: `{ id, label, disabled?, danger? }` or `{ separator: true }`; `where`: the `MouseEvent` or `{ x, y }`. Returns the chosen `id` or `null` |
| `RPGDesk.ui.openItem(id)`               | opens a sheet or scene from the library                                                                                                                            |
| `RPGDesk.ui.openLink(url)`              | opens an `http(s)` site in another tab, after the person confirms: `true` if it opened                                                                             |
| `RPGDesk.ui.copy(text)`                 | copies to the clipboard                                                                                                                                            |
| `RPGDesk.ui.download(name, data, type)` | offers a file to download: `data` is a text, `Blob` or `ArrayBuffer` (up to 20 MB)                                                                                 |

## Files, preferences and screen state

|                                                         |                                                                         |
| ------------------------------------------------------- | ----------------------------------------------------------------------- |
| `RPGDesk.files.pickImage()`                             | opens RPG Desk’s image picker: `{ id }` or `null`                       |
| `RPGDesk.files.url(id)`                                 | an address to show the file in an `<img>`                               |
| `RPGDesk.storage.get(key)`, `set(key, value)`, `keys()` | the person’s preferences, in this browser, for your plugin (up to 1 MB) |
| `RPGDesk.view.get(key)`, `set(key, value)`              | this sheet’s screen state; `get` answers right away (no promise)        |

## Webhooks

|                                     |                                                                                                                   |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `RPGDesk.webhooks.send(name, data)` | sends the data to the webhook declared in the manifest, through the server. Returns `{ ok, status, body, error }` |

See the `error` codes in [Webhooks on the sheet](https://docs.rpgdesk.com/en/fichas/webhooks/).

> **Errors**
>
> A refused request rejects the promise with an error (`RpgDeskError`), with the message in RPG Desk’s language. Errors that escape your code go to **Page errors**, in the room, and to the **Log**, in test mode.
