@nodaro/sdk 2.24.0 → 2.26.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 -1
- package/dist/index.cjs +46 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +174 -16
- package/dist/index.d.ts +174 -16
- package/dist/index.js +47 -7
- package/dist/index.js.map +1 -1
- package/dist/signup-signals.cjs +88 -0
- package/dist/signup-signals.cjs.map +1 -0
- package/dist/signup-signals.d.cts +55 -0
- package/dist/signup-signals.d.ts +55 -0
- package/dist/signup-signals.js +82 -0
- package/dist/signup-signals.js.map +1 -0
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -116,7 +116,8 @@ Voice / audio surface (client.voices, client.media, client.audio):
|
|
|
116
116
|
inspect speakers before paying, mix stems before rendering.
|
|
117
117
|
- Also: voices.change (single-voice), design / remix / dub;
|
|
118
118
|
client.media.downloadVideo (+downloadVideoProgress SSE) / trimVideo /
|
|
119
|
-
trimAudio / videoMetadata; client.audio.separate / isolate /
|
|
119
|
+
trimAudio / splitMedia / videoMetadata; client.audio.separate / isolate /
|
|
120
|
+
applyFx / mix.
|
|
120
121
|
|
|
121
122
|
Rules:
|
|
122
123
|
- Generations cost credits; catch InsufficientCreditsError (has .required /
|
package/dist/index.cjs
CHANGED
|
@@ -189,7 +189,7 @@ function throwFromResponse(status, body) {
|
|
|
189
189
|
throw new ForbiddenError(message, body.error?.missingScope);
|
|
190
190
|
}
|
|
191
191
|
if (status === 403) throw new ForbiddenError(message);
|
|
192
|
-
if (status === 404) throw new NotFoundError(message);
|
|
192
|
+
if (status === 404) throw new NotFoundError(body.error?.message ?? (typeof body.message === "string" ? body.message : void 0));
|
|
193
193
|
if (status === 429) throw new RateLimitedError(message);
|
|
194
194
|
if (status === 402) {
|
|
195
195
|
throw new InsufficientCreditsError(message, body.error?.required, body.error?.available);
|
|
@@ -539,8 +539,6 @@ var ExecutionsResource = class {
|
|
|
539
539
|
);
|
|
540
540
|
}
|
|
541
541
|
};
|
|
542
|
-
|
|
543
|
-
// src/resources/nodes.ts
|
|
544
542
|
var DEFAULT_POLL_MS = 2e3;
|
|
545
543
|
var DEFAULT_MAX_MS = 15 * 60 * 1e3;
|
|
546
544
|
var sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
@@ -558,6 +556,10 @@ var sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
558
556
|
}
|
|
559
557
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
560
558
|
});
|
|
559
|
+
function notRunnable(type, why) {
|
|
560
|
+
return new NodaroError(`Node type "${type}" has no route of its own to run it directly: ${why}.`, "node_not_runnable", 0);
|
|
561
|
+
}
|
|
562
|
+
var isRouteNotFound = (err) => err instanceof NotFoundError && /^Route\b.*\bnot found\b/i.test(err.message);
|
|
561
563
|
function extractJobId(result, label) {
|
|
562
564
|
if (result && typeof result === "object" && "jobId" in result) {
|
|
563
565
|
const jobId = result.jobId;
|
|
@@ -579,13 +581,20 @@ var NodesResource = class {
|
|
|
579
581
|
return this.client.request("GET", `/v1/nodes/${encodeURIComponent(type)}`);
|
|
580
582
|
}
|
|
581
583
|
run(type, params = {}, options = {}) {
|
|
582
|
-
const route = type === "
|
|
584
|
+
const route = type === "render-video" && typeof params.planType === "string" ? "/v1/render-video/plan" : shared.nodeRunRoute(type);
|
|
585
|
+
if (!route) return Promise.reject(notRunnable(type, shared.NODE_TYPES_WITHOUT_RUN_ROUTE[type]));
|
|
586
|
+
const platform = shared.SOCIAL_POST_NODE_PLATFORM[type];
|
|
587
|
+
const body = platform && params.platform === void 0 ? { ...params, platform } : params;
|
|
588
|
+
const conventional = !Object.prototype.hasOwnProperty.call(shared.NODE_RUN_ROUTES, type);
|
|
583
589
|
return this.client.request("POST", route, {
|
|
584
|
-
body
|
|
590
|
+
body,
|
|
585
591
|
// Transport-level retry safety, opt-in per call. The platform reads the
|
|
586
592
|
// standard header, so a caller that reuses a key on a retry gets the
|
|
587
593
|
// same run back instead of a second charge.
|
|
588
594
|
...options.idempotencyKey ? { headers: { "Idempotency-Key": options.idempotencyKey } } : {}
|
|
595
|
+
}).catch((err) => {
|
|
596
|
+
if (conventional && isRouteNotFound(err)) throw notRunnable(type, "it runs only inside a workflow (client.workflows.run)");
|
|
597
|
+
throw err;
|
|
589
598
|
});
|
|
590
599
|
}
|
|
591
600
|
async runAndWait(type, params = {}, opts = {}) {
|
|
@@ -2386,6 +2395,20 @@ var MediaResource = class {
|
|
|
2386
2395
|
trimAudio(input) {
|
|
2387
2396
|
return this.client.request("POST", "/v1/trim-audio", { body: input });
|
|
2388
2397
|
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Cut a video and/or an audio file into consecutive parts
|
|
2400
|
+
* (`POST /v1/split-media`). Every part is at most `chunkDuration` seconds and
|
|
2401
|
+
* at least `minPartDuration` (default 4, never above `chunkDuration`) — a
|
|
2402
|
+
* short leftover is evened out with the parts before it. Video is cut on
|
|
2403
|
+
* whole frames with each part's sound matching its picture; audio parts are
|
|
2404
|
+
* sample-exact, in `audioFormat` (`mp3` default / `wav` / `aac`). With both
|
|
2405
|
+
* sources each is split on its own. At most 200 parts per input. Poll
|
|
2406
|
+
* `jobs.get(jobId)`; the parts are on the completed job's `output_data` —
|
|
2407
|
+
* see {@link SplitMediaOutput}.
|
|
2408
|
+
*/
|
|
2409
|
+
splitMedia(input) {
|
|
2410
|
+
return this.client.request("POST", "/v1/split-media", { body: input });
|
|
2411
|
+
}
|
|
2389
2412
|
/**
|
|
2390
2413
|
* Turn one still image + one audio track into an MP4
|
|
2391
2414
|
* (`POST /v1/still-to-video`) — locally rendered (FFmpeg), no AI model,
|
|
@@ -2601,6 +2624,23 @@ var CreditsResource = class {
|
|
|
2601
2624
|
body: { models: ids.slice(0, MODEL_COSTS_LIMIT) }
|
|
2602
2625
|
});
|
|
2603
2626
|
}
|
|
2627
|
+
/**
|
|
2628
|
+
* `POST /v1/credits/claim-signup-grant` → claims the account's free signup
|
|
2629
|
+
* grant, once, with the browser signals of the page making the claim.
|
|
2630
|
+
*
|
|
2631
|
+
* Call it once per page load as soon as the session is known, and never
|
|
2632
|
+
* wait on it for rendering: it is idempotent (a decided account answers
|
|
2633
|
+
* with its state and `granted: false`), it costs the user nothing when it
|
|
2634
|
+
* fails (the next load asks again), and the signals are what make the
|
|
2635
|
+
* claim worth sending — collect them with `collectSignupKeys()` from
|
|
2636
|
+
* `@nodaro/sdk/signup-signals` and pass whatever came back, `{}` included.
|
|
2637
|
+
* Cloud-only route: a self-hosted instance answers 404.
|
|
2638
|
+
*/
|
|
2639
|
+
claimSignupGrant(keys = {}) {
|
|
2640
|
+
return this.client.request("POST", "/v1/credits/claim-signup-grant", {
|
|
2641
|
+
body: keys
|
|
2642
|
+
});
|
|
2643
|
+
}
|
|
2604
2644
|
// NOTE: no `estimate(...)` helper. The backend exposes
|
|
2605
2645
|
// `POST /v1/credits/estimate-workflow` (body `{ nodes }` → `{ data: {
|
|
2606
2646
|
// totalCredits, nodeCount } }`), but no consumer has a settled shape for it
|
|
@@ -4054,7 +4094,7 @@ var EditResource = class {
|
|
|
4054
4094
|
return shared.remapTranscriptThroughEdl(edl, transcript);
|
|
4055
4095
|
}
|
|
4056
4096
|
};
|
|
4057
|
-
var SDK_VERSION = "2.
|
|
4097
|
+
var SDK_VERSION = "2.26.0" ;
|
|
4058
4098
|
var CLIENT_HEADER = "X-Nodaro-Client";
|
|
4059
4099
|
var isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
4060
4100
|
var NodaroClient = class _NodaroClient {
|