# Biblioteca da comunidade

> Explore a biblioteca da comunidade do Nodaro em TypeScript, clone na sua conta personagens, locais e objetos, favorite-os e denuncie uma publicação.

Source: https://nodaro.ai/pt-BR/docs/developers/sdk/community

**`client.community`** lê a biblioteca da comunidade, a coleção compartilhada de personagens, locais e objetos selecionados pela equipe do Nodaro. Você pode explorar a biblioteca e buscar nela, ler uma publicação, clonar uma publicação na sua própria conta, favoritá-la e denunciá-la para moderação. Os métodos chamam a [API REST da comunidade](https://nodaro.ai/docs/developers/api/community). Veja [Biblioteca da comunidade](https://nodaro.ai/docs/guides/community-library) para conhecer o recurso e as regras de direito de imagem e de consentimento.

A biblioteca da comunidade existe nas instalações multiusuário: Nodaro Cloud e Business edition. Uma instalação da Community Edition, de um único usuário, responde a todas as chamadas com `NotFoundError`.

## Métodos
| Método | O que faz |
| --- | --- |
| [`browse(params?)`](#browseparams) | Explora as publicações e busca nelas |
| [`get(slug)`](#getslug) | Lê uma publicação |
| [`getFull(slug)`](#getfullslug) | Lê uma publicação com o snapshot público completo |
| [`favorites()`](#favorites) | Lista as publicações que você favoritou |
| [`clone(id, entityType)`](#cloneid-entitytype) | Copia uma publicação para a sua conta |
| [`favorite(id)`](#favoriteid) | Adiciona ou remove um favorito |
| [`report(id, reason)`](#reportid-reason) | Denuncia uma publicação para moderação |

Publicar não faz parte do SDK: os tokens pessoais e OAuth do SDK não podem publicar.

## client.community
Uma publicação é um `CommunityCard`. Os campos dela usam snake_case, como a API os envia. `CommunityEntityType` é `"character"`, `"location"` ou `"object"`.

### browse(params?)
Retorna uma página de publicações públicas e um `nextCursor` (`GET /v1/community/browse`). Passe `nextCursor` de volta como `cursor` para obter a próxima página; ele é `null` na última página.

```ts
browse(params?: BrowseCommunityParams): Promise<{ data: CommunityCard[]; nextCursor: string | null }>
```

<TypeTable
type={{
entityType: { type: '"character" | "location" | "object"', description: "Lista apenas este tipo de entidade." },
q: { type: 'string', description: "Busca no título, na descrição e nas tags." },
category: { type: 'string', description: "Lista apenas esta categoria." },
sort: { type: '"newest" | "popular"', default: '"newest"', description: "A ordem." },
cursor: { type: 'string', description: "O nextCursor da página anterior." },
limit: { type: 'number', default: '20', description: "O tamanho da página, no máximo 50." },
}}
/>

```ts
const { data: listings, nextCursor } = await client.community.browse({
entityType: "character",
sort: "popular",
limit: 20,
})
```

### get(slug)
Lê uma publicação pelo slug (`GET /v1/community/detail/:slug`).

```ts
get(slug: string): Promise<{ data: CommunityCard }>
```

<TypeTable
type={{
slug: { type: 'string', required: true, description: "O slug da publicação." },
}}
/>

```ts
const { data: listing } = await client.community.get("detective-mara")
```

Lança `NotFoundError` quando a publicação não existe ou não está mais ativa.

### getFull(slug)
Lê uma publicação com o snapshot público completo: imagens, voz e texto, como uma página de detalhes os mostra (`GET /v1/community/detail/:slug/full`).

```ts
getFull(slug: string): Promise<{ data: CommunityFullDetail }>
```

<TypeTable
type={{
slug: { type: 'string', required: true, description: "O slug da publicação." },
}}
/>

```ts
const { data: detail } = await client.community.getFull("detective-mara")
```

### favorites()
Lista as publicações que você favoritou (`GET /v1/community/favorites`).

```ts
favorites(): Promise<{ data: CommunityCard[] }>
```

```ts
const { data: favorites } = await client.community.favorites()
```

### clone(id, entityType)
Copia uma publicação para a sua biblioteca como uma **cópia independente** (`POST /v1/community/listings/:id/clone`). Os arquivos dela são copiados para o seu próprio armazenamento, então a cópia continua existindo quando o original muda ou é removido. Retorna o tipo e o ID da sua nova entidade.

```ts
clone(id: string, entityType: "character" | "location" | "object"): Promise<{ entityType: string; id: string }>
```

<TypeTable
type={{
id: { type: 'string', required: true, description: "O ID da publicação." },
entityType: { type: '"character" | "location" | "object"', required: true, description: "O tipo de entidade que a publicação contém." },
}}
/>

```ts
const { id: characterId } = await client.community.clone(listingId, "character")
const character = await client.characters.get(characterId)
```

Um token OAuth precisa do escopo `assets:write`. Lança `StorageExceededError` quando o seu armazenamento está cheio.

### favorite(id)
Adiciona uma publicação aos seus favoritos, ou a remove quando ela já está lá (`POST /v1/community/listings/:id/favorite`). Retorna o novo estado.

```ts
favorite(id: string): Promise<{ favorited: boolean }>
```

<TypeTable
type={{
id: { type: 'string', required: true, description: "O ID da publicação." },
}}
/>

```ts
const { favorited } = await client.community.favorite(listingId)
```

### report(id, reason)
Denuncia uma publicação para moderação (`POST /v1/community/listings/:id/report`).

```ts
report(id: string, reason: CommunityReportReason): Promise<{ ok: true }>
```

<TypeTable
type={{
id: { type: 'string', required: true, description: "O ID da publicação." },
reason: { type: '"real_person_no_consent" | "inappropriate" | "ip_violation" | "other"', required: true, description: "real_person_no_consent: mostra uma pessoa real sem consentimento. inappropriate: conteúdo impróprio. ip_violation: usa a propriedade intelectual de outra pessoa. other: qualquer outro motivo." },
}}
/>

```ts
await client.community.report(listingId, "real_person_no_consent")
```

## Frequently asked questions

### Como copiar um personagem da comunidade para a minha conta?

Chame client.community.clone com o ID da publicação e o tipo de entidade, como character. A cópia é sua e não muda quando o original muda. Ela conta no seu armazenamento.

### Posso publicar na biblioteca da comunidade com o SDK?

Não. Publicar não faz parte do SDK. O SDK pode explorar, ler, clonar, favoritar e denunciar publicações.

### Por que client.community responde 404 na minha instalação?

A biblioteca da comunidade existe no Nodaro Cloud e nas instalações da Business edition. Uma instalação da Community Edition, de um único usuário, não tem as rotas da comunidade e responde 404.

### Como denunciar uma publicação que mostra uma pessoa real sem consentimento?

Chame client.community.report com o ID da publicação e o motivo real_person_no_consent. A publicação vai para moderação.
