לקוח
יצירת לקוח של ה-SDK של Nodaro עם createClient: כתובת הבסיס, האימות, פסק הזמן וסביבת העבודה, וכל המשאבים שהלקוח חושף.
הלקוח הוא האובייקט ש-createClient() מחזירה: מופע של NodaroClient ששומר את כתובת הבסיס, את ספק האימות ואת ההגדרות שלכם, וחושף כל חלק של ה-API של Nodaro כמשאב, כמו client.workflows או client.nodes. יוצרים אותו פעם אחת ומשתמשים בו שוב בכל קריאה.
יצירת לקוח
import { createClient, StaticTokenAuth } from "@nodaro/sdk"
const client = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
timeoutMs: 120_000,
})createClient(options: ClientOptions): NodaroClientמאפיין
סוג
ה-SDK מייצא את NodaroClient גם כמחלקה, כך שאפשר להגדיר טיפוס לפונקציה שמקבלת לקוח:
import type { NodaroClient } from "@nodaro/sdk"
async function countWorkflows(client: NodaroClient, projectId: string) {
const { data } = await client.workflows.list({ projectId })
return data.length
}המשאבים של הלקוח
הפונקציה createClient יוצרת את כל המשאבים, וניגשים לכל משאב דרך client.<resource>.
| משאב | מה הוא מכסה | קריאה נוספת |
|---|---|---|
client.workflows | תהליכים: יצירה, עדכון, שיתוף, ייצוא, ייבוא והרצה | תהליכים ופרויקטים |
client.projects | הפרויקטים שבהם נמצאים התהליכים | תהליכים ופרויקטים |
client.sessions | סשנים של יצירה בתוך פרויקטים | תהליכים ופרויקטים |
client.executions | הרצות של תהליך שלם | משימות והרצות |
client.jobs | משימות יצירה בודדות, עם דירוגים ומסננים | משימות והרצות |
client.webhooks | נקודות קצה ש-Nodaro קורא להן כשמשימה מסתיימת | משימות והרצות |
client.videoPro | עצירה של הרצה ברכיב יצירת וידאו Pro, או הרצת המשך שלה | משימות והרצות |
client.nodes | קטלוג הרכיבים והרצות של רכיב יחיד | הרצת רכיבים |
client.apps | אפליקציות שפורסמו וההרצות שלהן | אפליקציות ותבניות |
client.templates | שוק התבניות | אפליקציות ותבניות |
client.tutorials | מדריכי וידאו ומדריכי תהליכים | אפליקציות ותבניות |
client.llm | פלט מובנה ממודל שפה | LLM ובחירת המיטב |
client.reduce | בחירה של התוצאה הטובה ביותר מתוך תוצאות רבות, או איחוד שלהן | LLM ובחירת המיטב |
client.uploads | העלאת קבצים | מדיה והעלאות |
client.library | המדיה ששמרתם | מדיה והעלאות |
client.gallery | הגלריה הציבורית והמועדפים שלכם | מדיה והעלאות |
client.media | הורדה, קיצוץ, הוספת כתוביות, הוספת שכבות וקולאז׳ של מדיה | מדיה והעלאות |
client.voices | קולות, החלפת קול, עיצוב קול ודיבוב | קולות ואודיו |
client.audio | הפרדה, בידוד, מיקס, קיצוץ ותמלול של אודיו | קולות ואודיו |
client.edit | זיהוי שקט, סנכרון אודיו, תוכניות עריכה ורינדור של EDL | עריכה |
client.scene3d | סצנות תלת־ממד שאפשר לערוך, ורינדור תלת־ממד Pro | סצנות תלת־ממד |
client.characters | דמויות | דמויות |
client.locations | מיקומים | מיקומים |
client.objects | אובייקטים ואביזרים | אובייקטים ויצורים |
client.creatures | חיות ויצורים | אובייקטים ויצורים |
client.community | ספריית הנכסים המשותפת של הקהילה | ספריית הקהילה |
client.studio | הפקות Studio | הפקות Studio |
client.shots | רשומות השוטים המשותפות שמאחורי קישורי שיתוף | הפקות Studio |
client.recast | הרצות של Recast ותסריטים שכתבתם | Recast ב-SDK |
client.castSwap | החלפת האנשים, חיות המחמד, המוצרים או המיקום בסרטון קצר, ב-Nodaro Cloud בלבד | ה-API של Nodaro Motion |
client.trends | מתכונים מוכנים של Nodaro Motion שרצים עם התמונות שלכם, ב-Nodaro Cloud בלבד | טרנדים |
client.pipelines | פייפליינים של סיפור ← וידאו | פייפליינים |
client.copilot | שיחות עם ה-Copilot, רק בתוך האפליקציה של Nodaro | Copilot ב-SDK |
client.models | קטלוג המודלים | מודלים וקרדיטים |
client.credits | היתרה שלכם והמחירים של המודלים | מודלים וקרדיטים |
client.billing | תוכניות, מחירים והמנוי שלכם | מודלים וקרדיטים |
client.pickerCatalogs | האפשרויות התקפות של כל בורר | בוררים, ערכות ופרומפטים |
client.catalogs | כל קטלוגי הבוררים בקריאה אחת | בוררים, ערכות ופרומפטים |
client.presets | ערכות שמורות וערכות מובנות של רכיבים | בוררים, ערכות ופרומפטים |
client.palettes | פלטות הצבעים שלכם | בוררים, ערכות ופרומפטים |
client.moodboards | המודבורדים שלכם | בוררים, ערכות ופרומפטים |
client.promptHelper | אשף הפרומפטים | בוררים, ערכות ופרומפטים |
client.organizations | ארגונים, חברים והזמנות | ארגונים וסביבות עבודה |
client.workspaces | סביבות עבודה, חברים וקודי הצטרפות | ארגונים וסביבות עבודה |
client.userSettings | ההגדרות שלכם: שפה, נראות בגלריה, הדוח החודשי במייל וההעדפות של תפריט הוספת רכיב ושל הקנבס | הגדרות משתמש |
client.developerApps | אפליקציות ה-OAuth שבבעלותכם | OAuth ויישומי מפתחים |
client.oauth | החלפת קוד באסימון, ביטול אסימונים ונתונים למסך ההסכמה | OAuth ויישומי מפתחים |
ללקוח עצמו יש עוד חמש מתודות: me(), connectedApps(), revokeConnectedApp(), withWorkspace() ו-request().
נקודות כניסה לכל משאב
החבילה הראשית, @nodaro/sdk, מייצאת הכל. כל משאב מתפרסם גם כנקודת כניסה משלו, @nodaro/sdk/<entry>, שטוענת רק את המשאב הזה ואת הטיפוסים שהוא מקבל ומחזיר. למשל @nodaro/sdk/jobs, @nodaro/sdk/nodes ו-@nodaro/sdk/workflows.
- ב-
@nodaro/sdk/clientנמצאיםcreateClient,NodaroClientוספקי האימות. - ב-
@nodaro/sdk/coreנמצאיםNodaroClientCoreואותם ספקי אימות. - ב-
@nodaro/sdk/errorsנמצאות מחלקות השגיאה ו-throwFromResponse. - כל נקודת כניסה אחרת נקראת על שם המשאב שלה. נקודת הכניסה
@nodaro/sdk/node-presetsהיאclient.presets, וב-@nodaro/sdk/webhooksנמצאת גם הפונקציהverifyWebhookSignature.
import { NotFoundError } from "@nodaro/sdk/errors"
import type { Job, JobStatus } from "@nodaro/sdk/jobs"ערך שמייבאים מנקודת כניסה זהה לערך שמייבאים מהחבילה הראשית, ולכן בדיקת instanceof NotFoundError עובדת בלי קשר לנתיב שממנו כל צד ייבא. הפונקציה createClient בונה את כל המשאבים, ולכן נקודת הכניסה @nodaro/sdk/client טוענת את כולם. תת־הנתיבים הישנים @nodaro/sdk/supabase ו-@nodaro/sdk/signup-signals לא השתנו.
לקוח עם המשאבים שאתם משתמשים בהם בלבד
המחלקה NodaroClientCore היא הלקוח בלי המשאבים שלו: האפשרויות ש-createClient מקבלת, מתודות הבקשה והמתודות me(), connectedApps() ו-revokeConnectedApp(). המחלקה NodaroClient מרחיבה אותה עם כל המשאבים. הרחיבו אותה בעצמכם רק עם המשאבים שאתם קוראים להם, והמודולים של שאר המשאבים לא נטענים אף פעם:
import { NodaroClientCore, StaticTokenAuth } from "@nodaro/sdk/core"
import { JobsResource } from "@nodaro/sdk/jobs"
import { NodesResource } from "@nodaro/sdk/nodes"
class AppClient extends NodaroClientCore {
readonly jobs = new JobsResource(this)
readonly nodes = new NodesResource(this) // polls through `jobs`
}
const client = new AppClient({ baseUrl: "https://app.nodaro.ai", auth: new StaticTokenAuth(token) })
await client.nodes.runAndWait("generate-image", { prompt: "a lighthouse at dusk" })כל מחלקת משאב מקבלת NodaroClientCore. המחלקה NodesResource צריכה את jobs על אותו לקוח, והמחלקה Scene3DResource צריכה את nodes: הטיפוסים של הבנאים שלהן מציינים זאת, ולכן קוד שמשמיט אחד מהם לא עובר קומפילציה. המתודה withWorkspace שייכת ל-NodaroClient. כדי לעבוד בסביבת עבודה, העבירו את workspaceId לבנאי.
מה המתודות מחזירות
- המעטפות נשמרות. כשנקודת קצה מחזירה
{ "data": ... }, המתודה מחזירה את המעטפת הזו, ולכן כותביםconst { data } = await client.workflows.get(id). ברשימות עם עמודים יש גם cursor לידdata, כמוnextCursor. - חלק מהמשאבים מחזירים את המטען עצמו. כמה מתודות פותחות את המעטפת של התגובה. למשל, המתודה
client.characters.list()מחזירה{ characters, nextCursor }, והמתודהclient.credits.balance()מחזירה את היתרה עצמה. בדף של כל משאב מופיע טיפוס ההחזרה המדויק. - מחיקות וביטולים מחזירים בדרך כלל
{ success: true }. - שמות השדות זהים לפורמט שה-API שולח. השדות של
Jobכתובים ב-snake_case, כמוoutput_dataו-created_at, כי כך ה-API שולח אותם. השדות שלWorkflowושלWorkflowExecutionכתובים ב-camelCase.
כל טיפוס של תגובה ושל קלט מיוצא, כך שאפשר לייבא אותו עם import type. ראו את הדף טיפוסים.
me()
me(): Promise<UserIdentity & MeOrganizations>מחזירה את הזהות שמאחורי האסימון הנוכחי (GET /v1/me). עם כל אסימון תקף, המתודה מחזירה את הבעלים שלו, בין שמדובר באסימון API, באסימון גישה של OAuth או בסשן בדפדפן. כשהאסימון חסר או לא תקין, המתודה זורקת UnauthorizedError.
const me = await client.me()
console.log(me.email, me.tier)| שדה | סוג | תיאור |
|---|---|---|
id | string | מזהה המשתמש ב-Nodaro. |
email | string | כתובת האימייל של המשתמש. |
displayName | string | null | שם התצוגה, או null כשהוא לא מוגדר. |
avatarUrl | string | null | כתובת ה-URL של האווטאר, או null כשהיא לא מוגדרת. |
tier | string | רמת המנוי השמורה, כמו "free" או "pro". כדי לדעת איזו רמה נאכפת בפועל, כולל תשלום לפי שימוש, קבלו את effectiveTier מ-client.credits.balance(). |
isAdmin | boolean | האם המשתמש הוא מנהל מערכת. השתמשו בשדה רק כדי להחליט מה להציג. השרת בודק בעצמו כל הרשאה. |
במופע של Nodaro Cloud עם ארגונים, התוצאה כוללת גם את organizations, workspaces, lastWorkspaceId ו-organizationsUnavailable. טפלו בכל אחד משלושת המצבים שלהם בדרך אחרת:
| מה רואים | מה זה אומר | מה לעשות |
|---|---|---|
| השדות לא מופיעים | במופע אין ארגונים | אל תציגו תפריט בחירת סביבת עבודה. |
| השדות מופיעים וריקים | החשבון לא שייך לאף ארגון | הציעו ליצור ארגון או להצטרף לארגון. |
organizationsUnavailable: true | הבדיקה נכשלה | שמרו על הבחירה הקיימת. אל תגידו למשתמש שהוא איבד גישה. |
connectedApps()
connectedApps(): Promise<ConnectedApp[]>מחזירה כל אפליקציה שיש לה גישה לחשבון של המשתמש המחובר (GET /v1/me/connected-apps), לפי מועד אישור הגישה, מהחדש לישן. הרשימה כוללת יישומי מפתחים, מחברי MCP של עוזרי AI והתקנות באירוח עצמי. אלה הנתונים שמסך הגדרות של אפליקציות מחוברות מציג. ראו את הדף אפליקציות OAuth כדי להבין מהו אישור גישה.
המתודה הזו דורשת סשן מחובר בדפדפן. היא מקבלת אסימון סשן מ-supabaseAuth() או מ-createSharedSupabaseClient. עם אסימון API (ndr_…) או אסימון של אפליקציה (ndr_app_…) היא זורקת UnauthorizedError, כך שאפליקציה לא יכולה לקבל רשימה של אישורי הגישה שהיא משתמשת בהם או לבטל אותם. אינטגרציה בצד השרת לא יכולה לקרוא לה.
const apps = await client.connectedApps()
// [{ authorizationId, name, kind, homepageUrl, scopes, connectedAt, lastUsedAt }]| שדה | סוג | תיאור |
|---|---|---|
authorizationId | string | אישור הגישה. העבירו אותו ל-revokeConnectedApp(). |
name | string | null | שם האפליקציה. לקוח MCP שרשם את עצמו בחר את השם שלו בעצמו. |
kind | DeveloperAppKind | user (יישום מפתחים), first_party_mcp, dynamic_mcp (לקוח MCP שרשם את עצמו) או community_instance (התקנה באירוח עצמי). |
homepageUrl | string | null | דף הבית של האפליקציה, אם היא ציינה אחד. |
scopes | DeveloperAppScope[] | ההרשאות שבאישור הגישה. |
connectedAt | string | מתי המשתמש אישר את הגישה, בפורמט ISO 8601. |
lastUsedAt | string | null | השימוש האחרון באסימון כלשהו שהונפק במסגרת אישור הגישה, או null אם אף פעם לא השתמשו בו. |
revokeConnectedApp(authorizationId)
revokeConnectedApp(authorizationId: string): Promise<void>מסיימת את הגישה של אפליקציה (POST /v1/me/connected-apps/:authorizationId/revoke). המתודה מבטלת מיד את אישור הגישה ואת כל אסימון שהונפק במסגרתו, ולכן הקריאה הבאה של האפליקציה נכשלת עם 401. כמו connectedApps(), גם היא דורשת סשן מחובר בדפדפן. כשאישור הגישה לא שייך למשתמש, או שהוא כבר בוטל, המתודה זורקת NotFoundError.
await client.revokeConnectedApp(app.authorizationId)client.userSettings
המשאב client.userSettings קורא ומשנה את ההגדרות של האדם המחובר עצמו: שפת הממשק, הנראות בגלריה, הדוח החודשי במייל וההעדפות של תפריט הוספת רכיב ושל הקנבס. אפשר גם לייבא אותו מ-@nodaro/sdk/user-settings. אפליקציה מציגה את ההגדרות שהיא צריכה, ושולחת בחזרה רק את השדות שהיא משנה.
| מתודה | נקודת קצה | הערות |
|---|---|---|
get() | GET /v1/user/settings | מחזירה UserSettings: { tier, publicOutputs, promptTemplates, textTemplates, preferredLocale, mcpPreferences, showRecentNodes, showMostUsedNodes, variableDisplayMode, nodeDoubleClickAction, monthlyStatementEmail }. כשאף אחד לא מחובר, היא זורקת UnauthorizedError. |
update(patch) | PATCH /v1/user/settings | משנה רק את השדות שאתם שולחים, ומחזירה את ההגדרות כפי שנשמרו, בלי tier. |
כללים ל-update(patch):
- השדות
promptTemplatesו-textTemplatesמחליפים את הערך השמור כולו, ולכן שלחו את המפה או את הרשימה המלאה. השרת משמיט מפתח תבנית שהוא לא מכיר, וגם ערך ששווה לברירת המחדל. - השדה
mcpPreferencesממוזג ציר אחר ציר. - הערך
publicOutputs: falseדורש ב-Nodaro Cloud את תוכנית Standard ומעלה. אחרת המתודה זורקתForbiddenError. - השדה
preferredLocaleמקבל אחת מהשפות ש-Nodaro תומך בהן (UserSettingsLocale). - כשערך לא תקין, או כשאין ב-
patchמה לשנות, המתודה זורקתNodaroErrorעם סטטוס 400 (validation_error). כשהפרופיל חסר, היא זורקתNotFoundError.
// The monthly statement toggle on a billing screen.
const { monthlyStatementEmail } = await client.userSettings.get()
await client.userSettings.update({ monthlyStatementEmail: !monthlyStatementEmail })הטיפוסים הם UserSettings, UserSettingsPatch, UserSettingsSaved, UserSettingsLocale, UserTextTemplate, UserMcpPreferences, VariableDisplayMode ו-NodeDoubleClickAction.
withWorkspace(workspaceId)
withWorkspace(workspaceId: string | null): NodaroClientמחזירה לקוח חדש שפועל ב-workspaceId. הלקוח החדש חולק עם המקורי את האימות, את כתובת הבסיס, את פסק הזמן ואת פונקציית ה-fetch. העבירו null כדי לעבוד במרחב האישי שלכם.
const classroom = client.withWorkspace(workspaceId)
await classroom.workflows.run(workflowId) // runs in the workspace
await client.workflows.run(workflowId) // runs in the personal spaceהמתודה מחזירה לקוח חדש במקום לשנות את הלקוח הנוכחי. לכן שתי פעולות שרצות באותו זמן על אותו לקוח אף פעם לא מתבלבלות בין סביבות העבודה שלהן.
סביבת העבודה קובעת את ההיקף, אף פעם לא את הגישה. היא בוחרת מאיזו סביבת עבודה נקראת רשימה, ואיפה נוצר פריט חדש. קריאה, שינוי, מחיקה או הרצה של פריט שאתם מציינים לפי מזהה נקבעים לפי סביבת העבודה של הפריט עצמו. כששוכחים לציין סביבת עבודה, העבודה שלכם לא נעלמת, וסביבת עבודה שגויה לא נותנת גישה לעבודה של אף אחד אחר.
ב-Nodaro Cloud, סביבות עבודה שייכות לארגונים. ראו את הדפים ארגונים וסביבות עבודה וסביבות עבודה.
request(method, path, options)
request<T>(method: string, path: string, options?: {
body?: unknown
query?: Record<string, string | number | boolean | undefined>
headers?: Record<string, string>
signal?: AbortSignal
}): Promise<T>שולחת בקשה לכל נקודת קצה, בשביל נקודות הקצה המעטות שעדיין אין להן מתודה במשאב. המתודה מוסיפה את כותרת האימות ואת סביבת העבודה שלכם, שולחת את body כ-JSON, מחילה את timeoutMs וזורקת את אותן שגיאות עם טיפוסים כמו מתודות המשאבים.
// The same request that client.jobs.list() sends
const page = await client.request<{ data: unknown[]; next: string | null }>("GET", "/v1/jobs", {
query: { type: "llm-structured", limit: 20 },
})גוף מסוג FormData נשלח כהעלאת multipart. ערכי שאילתה שהם undefined מושמטים. מדריך ה-REST API מפרט את כל נקודות הקצה ואת השדות שלהן.
פסקי זמן ו-fetch משלכם
האפשרות timeoutMs מבטלת בקשה שנמשכת יותר מהמגבלה, 60 שניות כברירת מחדל. רוב היצירות נמשכות יותר מכל פסק זמן סביר של HTTP, ולכן התחילו את היצירה ובדקו את סטטוס המשימה מדי כמה שניות: המתודה client.nodes.runAndWait() עושה את שני הדברים בשבילכם. מתודות ההזרמה, client.copilot.stream() ו-client.media.downloadVideoProgress(), לא מחילות את פסק הזמן, כי הן אמורות להישאר פתוחות במשך דקות.
העבירו fetch משלכם כדי לשנות את הדרך שבה הבקשות נשלחות:
- בדיקות. החזירו מ-mock אובייקטי
Responseמוכנים מראש. - ניסיונות חוזרים. עטפו את
fetchהגלובלי בפונקציית עזר שמנסה שוב כשמתקבלת תשובה 5xx. - מעקב. עטפו אותו בספריית המעקב או הניטור שלכם.
const client = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
fetch: (input, init) => tracedFetch(input, init),
})סביבות ריצה ודפדפנים
ה-SDK משתמש רק ב-fetch וב-URL, שהם גלובליים ב-Node.js 20 ומעלה, בדפדפנים מודרניים, ב-React Native, ב-Cloudflare Workers, ב-Deno וב-Bun. אין צורך ב-polyfill.
- CORS עם אסימוני OAuth. אפליקציית דפדפן שקוראת ל-Nodaro עם אסימון גישה של OAuth חייבת לרוץ על origin שמופיע ב-
allowedOriginsשל יישום המפתחים. ראו את הדף OAuth ויישומי מפתחים. - CORS עם סשן. אפליקציית דפדפן שמשתמשת ב-
supabaseAuthלא נבדקת מול הרשימה הזו. - תווית הלקוח. בשרת, ה-SDK שולח
X-Nodaro-Client: sdk/<version>, ו-Nodaro רושם אותה כמקור של כל משימה. בדפדפן, תווית ברירת המחדל לא נשלחת, כי כותרת ה-Originשל הדפדפן כבר מציינת את האפליקציה שלכם. ערךclientLabelשהגדרתם בעצמכם נשלח תמיד.
שאלות נפוצות
באיזו כתובת בסיס להשתמש עם ה-SDK של Nodaro?
כתובת הבסיס של ה-SDK היא https://app.nodaro.ai ב-Nodaro Cloud, והכתובת של המופע שלכם בהתקנה באירוח עצמי. באפליקציית דפדפן שמוגשת מאותו origin כמו Nodaro, השתמשו במחרוזת ריקה.
מהו פסק הזמן של בקשה כברירת מחדל?
פסק הזמן של כל בקשה הוא 60 שניות כברירת מחדל, ואפשר לשנות אותו באפשרות timeoutMs. יצירה נמשכת יותר זמן מכל בקשה, ולכן התחילו אותה ובדקו את סטטוס המשימה מדי כמה שניות, במקום להגדיל את פסק הזמן.
איך שולחים בקשות שפועלות בסביבת עבודה?
כדי לשלוח בקשות בסביבת עבודה, קראו ל-client.withWorkspace(workspaceId). המתודה מחזירה לקוח חדש שכל בקשה שלו פועלת בסביבת העבודה הזו, והלקוח המקורי ממשיך לעבוד במרחב האישי שלכם.
איך קוראים לנקודת קצה שאין לה מתודה ב-SDK?
לנקודת קצה שאין לה מתודה ב-SDK, קראו ל-client.request(method, path, options). המתודה שולחת את אותה כותרת אימות, מחילה את אותו פסק זמן וזורקת את אותן שגיאות עם טיפוסים כמו כל מתודה של משאב.
דפים קשורים
SDK ל-TypeScript
אימות
שגיאות
ארגונים וסביבות עבודה
טיפוסים
עודכן לאחרונה