# ספריית הקהילה

> עיון בספריית הקהילה של Nodaro מ-TypeScript, שכפול של דמויות, מיקומים ואובייקטים משותפים לחשבון שלכם, הוספה למועדפים ודיווח על פריט.

Source: https://nodaro.ai/he/docs/developers/sdk/community

**`client.community`** קורא את ספריית הקהילה: האוסף המשותף של דמויות, מיקומים ואובייקטים שצוות Nodaro בוחר בקפידה. אפשר לעיין בספרייה ולחפש בה, לקרוא פריט, לשכפל פריט לחשבון שלכם, להוסיף אותו למועדפים ולדווח עליו לבדיקה. המתודות קוראות לנקודות הקצה שבדף ה-API [ספריית הקהילה](https://nodaro.ai/docs/developers/api/community). המדריך [ספריית הקהילה](https://nodaro.ai/docs/guides/community-library) מתאר את היכולת עצמה ואת הכללים שלה לגבי דמיון לאנשים אמיתיים והסכמה.

ספריית הקהילה קיימת בהתקנות מרובות משתמשים: Nodaro Cloud ומהדורת Business. בהתקנה של מהדורת Community, שמיועדת למשתמש יחיד, כל קריאה נכשלת עם `NotFoundError`.

## מתודות
| מתודה | מה היא עושה |
| --- | --- |
| [`browse(params?)`](#browseparams) | עיון וחיפוש בפריטים |
| [`get(slug)`](#getslug) | קריאת פריט אחד |
| [`getFull(slug)`](#getfullslug) | קריאת פריט אחד עם תמונת המצב הציבורית המלאה שלו |
| [`favorites()`](#favorites) | רשימת הפריטים שהוספתם למועדפים |
| [`clone(id, entityType)`](#cloneid-entitytype) | העתקת פריט לחשבון שלכם |
| [`favorite(id)`](#favoriteid) | הוספה למועדפים או הסרה מהם |
| [`report(id, reason)`](#reportid-reason) | דיווח על פריט לבדיקה |

פרסום פריטים הוא לא חלק מה-SDK: אסימונים אישיים ואסימוני OAuth, שה-SDK עובד איתם, לא יכולים לפרסם.

## client.community
פריט הוא `CommunityCard`. השמות של השדות שלו כתובים ב-snake_case, כמו שה-API שולח אותם. הטיפוס `CommunityEntityType` הוא `"character"`, `"location"` או `"object"`.

### browse(params?)‎
מחזירה עמוד של פריטים ציבוריים ו-`nextCursor` (`GET /v1/community/browse`). כדי לקבל את העמוד הבא, שלחו את `nextCursor` בחזרה בפרמטר `cursor`; בעמוד האחרון הערך שלו הוא `null`.

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

<TypeTable
type={{
entityType: { type: '"character" | "location" | "object"', description: "רק נכסים מהסוג הזה." },
q: { type: 'string', description: "חיפוש בכותרת, בתיאור ובתגיות." },
category: { type: 'string', description: "רק פריטים מהקטגוריה הזו." },
sort: { type: '"newest" | "popular"', default: '"newest"', description: "סדר הפריטים." },
cursor: { type: 'string', description: "הערך nextCursor מהעמוד הקודם." },
limit: { type: 'number', default: '20', description: "גודל העמוד, עד 50." },
}}
/>

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

### get(slug)‎
מחזירה פריט אחד לפי המזהה בכתובת שלו, ה-slug (`GET /v1/community/detail/:slug`).

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

<TypeTable
type={{
slug: { type: 'string', required: true, description: "המזהה בכתובת של הפריט." },
}}
/>

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

כשהפריט לא קיים או שהוא כבר לא פעיל, המתודה זורקת `NotFoundError`.

### getFull(slug)‎
מחזירה פריט אחד עם תמונת המצב הציבורית המלאה שלו: התמונות, הקול והטקסט, כפי שדף הפרטים של הפריט מציג אותם (`GET /v1/community/detail/:slug/full`).

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

<TypeTable
type={{
slug: { type: 'string', required: true, description: "המזהה בכתובת של הפריט." },
}}
/>

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

### favorites()‎
מחזירה את הפריטים שהוספתם למועדפים (`GET /v1/community/favorites`).

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

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

### clone(id, entityType)‎
מעתיקה פריט לספרייה שלכם כ**עותק עצמאי** (`POST /v1/community/listings/:id/clone`). הקבצים של הפריט מועתקים לאחסון שלכם, ולכן העותק נשאר כמו שהוא גם כשהמקור משתנה או נמחק. המתודה מחזירה את הסוג ואת המזהה של הנכס החדש שלכם.

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

<TypeTable
type={{
id: { type: 'string', required: true, description: "מזהה הפריט." },
entityType: { type: '"character" | "location" | "object"', required: true, description: "סוג הנכס שבפריט." },
}}
/>

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

אסימון OAuth צריך את ההרשאה `assets:write`. כשהאחסון שלכם מלא, המתודה זורקת `StorageExceededError`.

### favorite(id)‎
מוסיפה פריט למועדפים שלכם, או מסירה אותו מהם כשהוא כבר שם (`POST /v1/community/listings/:id/favorite`). המתודה מחזירה את המצב החדש.

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

<TypeTable
type={{
id: { type: 'string', required: true, description: "מזהה הפריט." },
}}
/>

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

### report(id, reason)‎
מדווחת על פריט לבדיקה (`POST /v1/community/listings/:id/report`).

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

<TypeTable
type={{
id: { type: 'string', required: true, description: "מזהה הפריט." },
reason: { type: '"real_person_no_consent" | "inappropriate" | "ip_violation" | "other"', required: true, description: "הסיבה לדיווח. real_person_no_consent: הפריט מציג אדם אמיתי בלי הסכמה. inappropriate: תוכן לא הולם. ip_violation: הפריט משתמש בקניין רוחני של מישהו אחר. other: כל סיבה אחרת." },
}}
/>

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

## client.keepers
**`client.keepers`** קורא את **Nodaro Keepers**, המדף המשותף של דמויות, יצורים, מיקומים ואובייקטים שמנהלי הפלטפורמה בוחרים, ומעתיק פריט מהמדף לחשבון שלכם. המתודות קוראות לנתיבים שבדף ה-API [Nodaro Keepers: הקטלוג המשותף](https://nodaro.ai/docs/developers/api/community#keepers). קריאת המדף לא דורשת פרטי גישה, ולכן גם אורח יכול לעיין בו. הקריאה וההעתקה לא עולות קרדיטים.

### catalog(params?)‎
מחזירה עמוד אחד של המדף: `{ data: KeeperCatalogItem[], next }`.

```ts
catalog(params?: { kind?: KeeperKind; cursor?: string; limit?: number }): Promise<KeeperCatalogPage>
```

<TypeTable
type={{
kind: { type: '"character" | "creature" | "location" | "object"', description: "רק הסוג הזה. בלי kind, העמוד עובר על הסוגים לפי הסדר הזה." },
limit: { type: 'number', default: '50', description: "מ-1 עד 200." },
cursor: { type: 'string', description: "הערך next מהעמוד הקודם. בעמוד האחרון הוא null." },
}}
/>

כל פריט הוא `{ id, kind, name, description, imageUrl, previewUrl, category, sort, createdAt }`. השדה `previewUrl` הוא עותק של התמונה הראשית ברוחב 480 פיקסלים, לתצוגה באריח. השדה `category` הוא הכותרת על המדף, והשדה `sort` קובע את הסדר על המדף. במדף יש רק שדות תצוגה. התגובה נשמרת במטמון לדקה, וכתובת IP אחת יכולה לקרוא את המדף עד 60 פעמים בדקה.

```ts
const { data, next } = await client.keepers.catalog({ kind: "character" })
```

### copy(kind, id)‎
מעתיקה פריט מהמדף לחשבון שלכם ומחזירה `{ id, name, kind, created }`. השדה `id` מזהה את הרשומה שלכם: טענו אותה עם `client.characters.get(id)` ועם שאר המתודות של הנכסים.

```ts
copy(kind: KeeperKind, id: string): Promise<CopyKeeperResult>
```

- העותק כולל את הטקסט הציבורי, את התמונה הראשית ואת הקבצים של הווריאנטים. כל קובץ מועתק לאחסון שלכם ונספר בו.
- קול מוכן מראש או קול מהספרייה עובר לעותק. מקול מותאם אישית או משוכפל נשארים רק השם והדוגמה שלו. הבחירות של הבעלים בבוררים, תמונות הייחוס ושדות המודל המאומן אף פעם לא עוברים.
- העותק נכנס לפרויקט ברירת המחדל שלכם. העותק לא משתנה כשהמקור משתנה.
- עותק אחד לכל אדם ולכל פריט: קריאה מאוחרת יותר מחזירה את אותו עותק עם `created: false`. עותק שהעברתם לארכיון חוזר מהארכיון, ועותק שכבר יש לכם נשאר שלכם, בין שהפריט עדיין על המדף ובין שלא.
- המתודה זורקת `NotFoundError` על פריט שלא נמצא על המדף כשאין לכם עותק שלו, שגיאת `413 storage_limit_exceeded` כשהקבצים שלו לא נכנסים באחסון שלכם, ו-`ForbiddenError` עם `personal_space_disabled` כשהארגון שלכם סגר את המרחב האישי.
- אסימון של אפליקציית OAuth צריך את ההרשאה `assets:write`.

```ts
const { id } = await client.keepers.copy("character", item.id)
const mine = await client.characters.get(id)
```

## שאלות נפוצות

### איך מעתיקים דמות מספריית הקהילה לחשבון שלי?

קראו ל-client.community.clone עם המזהה של הפריט ועם סוג הנכס, למשל character. העותק שייך לכם, והוא לא משתנה כשהמקור משתנה. העותק תופס מקום באחסון שלכם.

### האם אפשר לפרסם בספריית הקהילה עם ה-SDK?

לא. פרסום הוא לא חלק מה-SDK. ה-SDK יכול לעיין בפריטים, לקרוא אותם, לשכפל אותם, להוסיף אותם למועדפים ולדווח עליהם.

### למה client.community מחזיר 404 בהתקנה שלי?

ספריית הקהילה קיימת ב-Nodaro Cloud ובהתקנות של מהדורת Business. בהתקנה של מהדורת Community, שמיועדת למשתמש יחיד, אין נתיבים של ספריית הקהילה, וכל קריאה נדחית עם 404.

### איך מדווחים על פריט שמציג אדם אמיתי בלי הסכמה?

קראו ל-client.community.report עם המזהה של הפריט ועם הסיבה real_person_no_consent. הפריט עובר לבדיקה.

### איך משתמשים בדמות מ-Nodaro Keepers דרך ה-SDK?

קבלו את המדף עם client.keepers.catalog, ואז קראו ל-client.keepers.copy עם הסוג והמזהה של הפריט. העותק הוא דמות משלכם, וההעתקה לא עולה קרדיטים.
