@nodaro/sdk 2.19.0 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +149 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -31
- package/dist/index.d.ts +329 -31
- package/dist/index.js +149 -17
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ Core pattern (all generation is async; runAndWait submits + polls + resolves):
|
|
|
76
76
|
auth: new StaticTokenAuth(process.env.NODARO_ACCESS_TOKEN!),
|
|
77
77
|
})
|
|
78
78
|
const img = await client.nodes.runAndWait("generate-image", {
|
|
79
|
-
prompt: "…", provider: "nano-banana-2",
|
|
79
|
+
prompt: "…", provider: "nano-banana-2-1", // fast + cheap, great default
|
|
80
80
|
})
|
|
81
81
|
const vid = await client.nodes.runAndWait("generate-video", {
|
|
82
82
|
prompt: "…", imageUrl: img.imageUrl,
|
|
@@ -137,7 +137,7 @@ A proven first build (text in → video out). Paste after the primer:
|
|
|
137
137
|
|
|
138
138
|
```text
|
|
139
139
|
Build a small web app — "animated postcard":
|
|
140
|
-
1. A prompt box. On submit: generate-image (nano-banana-2) with the prompt.
|
|
140
|
+
1. A prompt box. On submit: generate-image (nano-banana-2-1) with the prompt.
|
|
141
141
|
2. Show the image IMMEDIATELY when it resolves.
|
|
142
142
|
3. Then generate-video (seedance-2-fast, duration 4) with that image as
|
|
143
143
|
imageUrl and prompt "subtle cinematic motion".
|
package/dist/index.cjs
CHANGED
|
@@ -300,6 +300,34 @@ var WorkflowsResource = class {
|
|
|
300
300
|
{ body: params }
|
|
301
301
|
);
|
|
302
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Render final (`renderFinal` on `POST /v1/workflows/:id/run`): run the
|
|
305
|
+
* render at Final for this run only, and every node after it, continuing the
|
|
306
|
+
* execution that stopped at its preview. The server derives the nodes and
|
|
307
|
+
* the override — send nothing else. Quote it first with
|
|
308
|
+
* {@link estimateRenderFinal}. Refused with `render_final_node_not_found`,
|
|
309
|
+
* `render_final_not_a_render`, or a continuation code (see `run`); a run
|
|
310
|
+
* its payer cannot cover throws `InsufficientCreditsError` (with `required`
|
|
311
|
+
* and, when it is yours to see, `available`) before any execution exists.
|
|
312
|
+
*/
|
|
313
|
+
renderFinal(id, params) {
|
|
314
|
+
return this.client.request("POST", `/v1/workflows/${encodeURIComponent(id)}/run`, {
|
|
315
|
+
body: {
|
|
316
|
+
renderFinal: { renderNodeId: params.renderNodeId },
|
|
317
|
+
continueFromExecutionId: params.continueFromExecutionId
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Quote a Render final (`POST /v1/workflows/:id/render-final/estimate`): the
|
|
323
|
+
* nodes it will run, the override it runs with and its estimated credits.
|
|
324
|
+
* Nothing is created or charged.
|
|
325
|
+
*/
|
|
326
|
+
estimateRenderFinal(id, params) {
|
|
327
|
+
return this.client.request("POST", `/v1/workflows/${encodeURIComponent(id)}/render-final/estimate`, {
|
|
328
|
+
body: { renderNodeId: params.renderNodeId, continueFromExecutionId: params.continueFromExecutionId }
|
|
329
|
+
});
|
|
330
|
+
}
|
|
303
331
|
/**
|
|
304
332
|
* Export a workflow as a portable JSON bundle.
|
|
305
333
|
* Pass `opts.assets = true` to include character/object/location entity data.
|
|
@@ -2078,13 +2106,21 @@ var VoicesResource = class {
|
|
|
2078
2106
|
}
|
|
2079
2107
|
/**
|
|
2080
2108
|
* Voice a multi-speaker script as ONE audio file
|
|
2081
|
-
* (`POST /v1/text-to-dialogue
|
|
2082
|
-
*
|
|
2083
|
-
*
|
|
2084
|
-
*
|
|
2085
|
-
*
|
|
2086
|
-
*
|
|
2087
|
-
*
|
|
2109
|
+
* (`POST /v1/text-to-dialogue`) on ElevenLabs Dialogue v3 — the default — or
|
|
2110
|
+
* Dialogue v4 (`provider: "elevenlabs-dialogue-v4"`). Each `dialogue` line is
|
|
2111
|
+
* `{ text, voice }` in speaking order — `voice` is a premade voice name or an
|
|
2112
|
+
* ElevenLabs voice UUID (cloned/library voices work too; mixed casts are
|
|
2113
|
+
* fine). At most 5,000 characters total across lines on Dialogue v3 and
|
|
2114
|
+
* 10,000 on Dialogue v4 (≤2,000 recommended for best quality) and 10 unique
|
|
2115
|
+
* voices. Line text may
|
|
2116
|
+
* carry `[audio tags]` like `[laughs]`. Costs credits and runs async — poll
|
|
2117
|
+
* `jobs.get(jobId)` for `output_data.audioUrl` and — on every dialogue model,
|
|
2118
|
+
* since both return timings at no extra credits — `output_data.transcript`, a
|
|
2119
|
+
* `Transcript` (`@nodaro/shared`): `words[]` with `startMs` / `endMs` /
|
|
2120
|
+
* `speaker` and one `segments[]` entry per line, `speaker` being the line's
|
|
2121
|
+
* `voice` as you sent it. Pass `transcript.words` to
|
|
2122
|
+
* `addCaptions({ captions, autoTranscribe: false })` to caption the dialogue
|
|
2123
|
+
* without a second transcription.
|
|
2088
2124
|
*/
|
|
2089
2125
|
textToDialogue(input) {
|
|
2090
2126
|
return this.client.request("POST", "/v1/text-to-dialogue", { body: input });
|
|
@@ -2440,7 +2476,14 @@ var AudioResource = class {
|
|
|
2440
2476
|
/**
|
|
2441
2477
|
* Layer multiple audio tracks into one (`POST /v1/mix-audio`). `audioUrls`
|
|
2442
2478
|
* (2–20) are summed; optional `trackVolumes` (0–200% each, positionally) set
|
|
2443
|
-
* per-track level.
|
|
2479
|
+
* per-track level. `duck` puts a music bed under speech: every track EXCEPT
|
|
2480
|
+
* `duck.under` (the 0-based index of the voice track) dips while that track
|
|
2481
|
+
* is loud and rises back in its pauses (sidechain compression). `amount`
|
|
2482
|
+
* (0–100, default 75) is how hard; `thresholdDb` (-60–0, default -30),
|
|
2483
|
+
* `ratio` (1–20, overrides `amount`), `attackMs` (1–2000, default 20) and
|
|
2484
|
+
* `releaseMs` (10–9000, default 500) are optional fine controls. A ducked mix
|
|
2485
|
+
* sums its tracks rather than averaging them, so the voice keeps its level;
|
|
2486
|
+
* the price is the same with or without a duck.
|
|
2444
2487
|
*/
|
|
2445
2488
|
mix(input) {
|
|
2446
2489
|
return this.client.request("POST", "/v1/mix-audio", { body: input });
|
|
@@ -2655,6 +2698,66 @@ var SavedPostsResource = class {
|
|
|
2655
2698
|
}
|
|
2656
2699
|
};
|
|
2657
2700
|
|
|
2701
|
+
// src/resources/collections.ts
|
|
2702
|
+
var CollectionsResource = class {
|
|
2703
|
+
constructor(client) {
|
|
2704
|
+
this.client = client;
|
|
2705
|
+
}
|
|
2706
|
+
client;
|
|
2707
|
+
/** `GET /v1/collections` → your collections with their record counts, whether the server has collections at all, and your caps. */
|
|
2708
|
+
list() {
|
|
2709
|
+
return this.client.request("GET", "/v1/collections");
|
|
2710
|
+
}
|
|
2711
|
+
/** `GET /v1/collections/:id` → one collection. */
|
|
2712
|
+
get(id) {
|
|
2713
|
+
return this.client.request("GET", `/v1/collections/${encodeURIComponent(id)}`);
|
|
2714
|
+
}
|
|
2715
|
+
/** `POST /v1/collections` → a new collection (`409 name_taken` when you have one by that name, `403 collection_limit_reached` at your cap). */
|
|
2716
|
+
create(input) {
|
|
2717
|
+
return this.client.request("POST", "/v1/collections", { body: input });
|
|
2718
|
+
}
|
|
2719
|
+
/** `PATCH /v1/collections/:id` → rename or re-describe a collection. */
|
|
2720
|
+
update(id, input) {
|
|
2721
|
+
return this.client.request("PATCH", `/v1/collections/${encodeURIComponent(id)}`, { body: input });
|
|
2722
|
+
}
|
|
2723
|
+
/** `DELETE /v1/collections/:id` → remove a collection and every record in it. */
|
|
2724
|
+
async delete(id) {
|
|
2725
|
+
await this.client.request("DELETE", `/v1/collections/${encodeURIComponent(id)}`);
|
|
2726
|
+
}
|
|
2727
|
+
/** `GET /v1/collections/:id/records` → the records, newest first. Narrow with `q` (words) and `since` (ISO); page with `cursor` / `limit` (1-100, default 50). */
|
|
2728
|
+
records(id, params = {}) {
|
|
2729
|
+
return this.client.request("GET", `/v1/collections/${encodeURIComponent(id)}/records`, {
|
|
2730
|
+
query: { q: params.q, since: params.since, cursor: params.cursor, limit: params.limit }
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
/**
|
|
2734
|
+
* `POST /v1/collections/:id/records` → save one record. Give the fields, or
|
|
2735
|
+
* `item` (any JSON — a feed post, a search result) and let the server map it;
|
|
2736
|
+
* explicit fields win. `outcome` is `inserted`, `duplicate` (the same link or
|
|
2737
|
+
* dedupe key is already there — the existing record comes back) or `replayed`
|
|
2738
|
+
* (a write with the same `idempotencyKey` already happened).
|
|
2739
|
+
*/
|
|
2740
|
+
addRecord(id, input, opts = {}) {
|
|
2741
|
+
return this.client.request("POST", `/v1/collections/${encodeURIComponent(id)}/records`, {
|
|
2742
|
+
body: input,
|
|
2743
|
+
...opts.idempotencyKey ? { headers: { "Idempotency-Key": opts.idempotencyKey } } : {}
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
/** `DELETE /v1/collections/:id/records/:recordId` → remove one record. */
|
|
2747
|
+
async deleteRecord(id, recordId) {
|
|
2748
|
+
await this.client.request(
|
|
2749
|
+
"DELETE",
|
|
2750
|
+
`/v1/collections/${encodeURIComponent(id)}/records/${encodeURIComponent(recordId)}`
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2753
|
+
/** `GET /v1/collections/:id/export` → the whole collection as CSV (default) or JSON text, newest first; `since` and `q` narrow it. */
|
|
2754
|
+
export(id, params = {}) {
|
|
2755
|
+
return this.client.requestText("GET", `/v1/collections/${encodeURIComponent(id)}/export`, {
|
|
2756
|
+
query: { format: params.format, since: params.since, q: params.q }
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
|
|
2658
2761
|
// src/resources/competitors.ts
|
|
2659
2762
|
var CompetitorsResource = class {
|
|
2660
2763
|
constructor(client) {
|
|
@@ -2663,12 +2766,37 @@ var CompetitorsResource = class {
|
|
|
2663
2766
|
client;
|
|
2664
2767
|
/** `GET /v1/competitors` → every tracked brand. */
|
|
2665
2768
|
async list() {
|
|
2666
|
-
const res = await this.
|
|
2667
|
-
return res.data;
|
|
2769
|
+
const res = await this.listWithPlan();
|
|
2770
|
+
return [...res.data];
|
|
2668
2771
|
}
|
|
2669
|
-
/** `GET /v1/competitors
|
|
2670
|
-
|
|
2671
|
-
return this.client.request("GET",
|
|
2772
|
+
/** `GET /v1/competitors` → every tracked brand, with how many months of scans your plan keeps. */
|
|
2773
|
+
listWithPlan() {
|
|
2774
|
+
return this.client.request("GET", "/v1/competitors");
|
|
2775
|
+
}
|
|
2776
|
+
/**
|
|
2777
|
+
* `GET /v1/competitors/:id` → one brand with its latest scan (posts and
|
|
2778
|
+
* cards) and its scan history; with `scan`, the brand as of that scan.
|
|
2779
|
+
*/
|
|
2780
|
+
get(id, options = {}) {
|
|
2781
|
+
const query = options.scan ? `?scan=${encodeURIComponent(options.scan)}` : "";
|
|
2782
|
+
return this.client.request("GET", `/v1/competitors/${encodeURIComponent(id)}${query}`);
|
|
2783
|
+
}
|
|
2784
|
+
/** `GET /v1/competitors/:id/history` → the brand's scans oldest first, per platform what each found and read (free). */
|
|
2785
|
+
history(id) {
|
|
2786
|
+
return this.client.request("GET", `/v1/competitors/${encodeURIComponent(id)}/history`);
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* `GET /v1/competitors/:id/compare` → the brand over a period, and over a
|
|
2790
|
+
* second one to compare with (free). A post belongs to a period by its
|
|
2791
|
+
* publish date; a period is at most a year.
|
|
2792
|
+
*/
|
|
2793
|
+
compare(id, input) {
|
|
2794
|
+
const params = new URLSearchParams({ from: input.from, to: input.to });
|
|
2795
|
+
if (input.vsFrom !== void 0 && input.vsTo !== void 0) {
|
|
2796
|
+
params.set("vsFrom", input.vsFrom);
|
|
2797
|
+
params.set("vsTo", input.vsTo);
|
|
2798
|
+
}
|
|
2799
|
+
return this.client.request("GET", `/v1/competitors/${encodeURIComponent(id)}/compare?${params.toString()}`);
|
|
2672
2800
|
}
|
|
2673
2801
|
/** `POST /v1/competitors` → track a brand. Accounts take handles or links. */
|
|
2674
2802
|
create(input) {
|
|
@@ -3761,6 +3889,8 @@ var EditResource = class {
|
|
|
3761
3889
|
...input.output !== void 0 ? { output: input.output } : {},
|
|
3762
3890
|
...input.quality !== void 0 ? { quality: input.quality } : {},
|
|
3763
3891
|
...input.crossfadeMs !== void 0 ? { crossfadeMs: input.crossfadeMs } : {},
|
|
3892
|
+
...input.clipKey !== void 0 ? { clipKey: input.clipKey } : {},
|
|
3893
|
+
...input.planBasis !== void 0 ? { planBasis: input.planBasis } : {},
|
|
3764
3894
|
...input.workflowId !== void 0 ? { workflowId: input.workflowId } : {}
|
|
3765
3895
|
}
|
|
3766
3896
|
});
|
|
@@ -3769,8 +3899,8 @@ var EditResource = class {
|
|
|
3769
3899
|
* Plan a transcript-driven cut (`POST /v1/edit-plan`). Reads a timed
|
|
3770
3900
|
* transcript (plus optional silence ranges) and the media sources, and plans
|
|
3771
3901
|
* the edit. The finished job's `output_data` holds the plan: an `Edl`
|
|
3772
|
-
* (`"tighten"`), an {@link EdlClipSet} (`"clips"`), or a
|
|
3773
|
-
* (`"chapters"`) — normalize it with {@link unwrapEditPlanOutput}.
|
|
3902
|
+
* (`"tighten"` or `"trailer"`), an {@link EdlClipSet} (`"clips"`), or a
|
|
3903
|
+
* {@link ChapterSet} (`"chapters"`) — normalize it with {@link unwrapEditPlanOutput}.
|
|
3774
3904
|
*
|
|
3775
3905
|
* On a self-hosted install the request relays to nodaro.ai and needs the
|
|
3776
3906
|
* install connected (a 503 `code: "nodaro_connection_required"` otherwise);
|
|
@@ -3845,7 +3975,7 @@ var EditResource = class {
|
|
|
3845
3975
|
return shared.remapTranscriptThroughEdl(edl, transcript);
|
|
3846
3976
|
}
|
|
3847
3977
|
};
|
|
3848
|
-
var SDK_VERSION = "2.
|
|
3978
|
+
var SDK_VERSION = "2.21.0" ;
|
|
3849
3979
|
var CLIENT_HEADER = "X-Nodaro-Client";
|
|
3850
3980
|
var isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3851
3981
|
var NodaroClient = class _NodaroClient {
|
|
@@ -3892,6 +4022,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3892
4022
|
library;
|
|
3893
4023
|
presets;
|
|
3894
4024
|
savedPosts;
|
|
4025
|
+
collections;
|
|
3895
4026
|
competitors;
|
|
3896
4027
|
pickerCatalogs;
|
|
3897
4028
|
catalogs;
|
|
@@ -3942,6 +4073,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3942
4073
|
this.library = new LibraryResource(this);
|
|
3943
4074
|
this.presets = new PresetsResource(this);
|
|
3944
4075
|
this.savedPosts = new SavedPostsResource(this);
|
|
4076
|
+
this.collections = new CollectionsResource(this);
|
|
3945
4077
|
this.competitors = new CompetitorsResource(this);
|
|
3946
4078
|
this.pickerCatalogs = new PickerCatalogsResource(this);
|
|
3947
4079
|
this.catalogs = new CatalogsResource(this);
|
|
@@ -4218,6 +4350,7 @@ exports.CREATURE_ASSET_TYPES = CREATURE_ASSET_TYPES;
|
|
|
4218
4350
|
exports.CallbackAuth = CallbackAuth;
|
|
4219
4351
|
exports.CatalogsResource = CatalogsResource;
|
|
4220
4352
|
exports.CharactersResource = CharactersResource;
|
|
4353
|
+
exports.CollectionsResource = CollectionsResource;
|
|
4221
4354
|
exports.CommunityResource = CommunityResource;
|
|
4222
4355
|
exports.CompetitorsResource = CompetitorsResource;
|
|
4223
4356
|
exports.CopilotResource = CopilotResource;
|