@nodaro/sdk 2.1.0 → 2.2.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/dist/index.cjs CHANGED
@@ -538,13 +538,19 @@ var NodesResource = class {
538
538
  get(type) {
539
539
  return this.client.request("GET", `/v1/nodes/${encodeURIComponent(type)}`);
540
540
  }
541
- run(type, params = {}) {
541
+ run(type, params = {}, options = {}) {
542
542
  const route = type === "generate-3d-scene" ? "/v1/3d-scene/generate" : type === "edit-3d-scene" ? "/v1/3d-scene/edit" : type === "render-video" && typeof params.planType === "string" ? "/v1/render-video/plan" : `/v1/${encodeURIComponent(type)}`;
543
- return this.client.request("POST", route, { body: params });
543
+ return this.client.request("POST", route, {
544
+ body: params,
545
+ // Transport-level retry safety, opt-in per call. The platform reads the
546
+ // standard header, so a caller that reuses a key on a retry gets the
547
+ // same run back instead of a second charge.
548
+ ...options.idempotencyKey ? { headers: { "Idempotency-Key": options.idempotencyKey } } : {}
549
+ });
544
550
  }
545
551
  async runAndWait(type, params = {}, opts = {}) {
546
552
  if (opts.signal?.aborted) throw new JobAbortedError();
547
- const result = await this.run(type, params);
553
+ const result = await this.run(type, params, { idempotencyKey: opts.idempotencyKey });
548
554
  const jobId = extractJobId(result, type);
549
555
  return this.pollJob(jobId, type, opts);
550
556
  }
@@ -605,6 +611,10 @@ var NodesResource = class {
605
611
  }
606
612
  }
607
613
  };
614
+ function newIdempotencyKey() {
615
+ const random = globalThis.crypto?.randomUUID?.();
616
+ return `sdk-pro3d-${random ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`}`;
617
+ }
608
618
  var Scene3DResource = class {
609
619
  constructor(client) {
610
620
  this.client = client;
@@ -613,6 +623,22 @@ var Scene3DResource = class {
613
623
  capabilities() {
614
624
  return this.client.request("GET", "/v1/3d-scene/capabilities");
615
625
  }
626
+ /** Current access to both the delivery and its source is required on every read. */
627
+ getDelivery(jobId) {
628
+ return this.client.request("GET", `/v1/3d-scene/deliveries/${encodeURIComponent(jobId)}`);
629
+ }
630
+ deliveryAssetBytes(jobId, asset, options) {
631
+ if (asset.kind !== "poster" && asset.kind !== "validation-report" || asset.usage !== (asset.kind === "poster" ? "poster" : "validation")) {
632
+ throw new Error("This asset is not available through the delivery endpoint");
633
+ }
634
+ if (!Number.isSafeInteger(asset.byteLength) || asset.byteLength < 1 || asset.byteLength > shared.SCENE3D_V2_LIMITS.maxRendererAssetBytes) {
635
+ throw new Error("Invalid scene delivery asset byte length");
636
+ }
637
+ return this.client.requestBytes("GET", `/v1/3d-scene/deliveries/${encodeURIComponent(jobId)}/assets/${encodeURIComponent(asset.assetId)}`, {
638
+ signal: options?.signal,
639
+ maxBytes: asset.byteLength
640
+ });
641
+ }
616
642
  /** Persist deterministic overlays without an LLM or a generation charge. */
617
643
  applyEdits(revisionId, params) {
618
644
  return this.client.request("POST", `/v1/3d-scene/revisions/${encodeURIComponent(revisionId)}/edits`, { body: params });
@@ -649,6 +675,53 @@ var Scene3DResource = class {
649
675
  editAndWait(params, options) {
650
676
  return this.client.nodes.runAndWait("edit-3d-scene", params, options);
651
677
  }
678
+ /**
679
+ * Price a 3D Render Pro request WITHOUT starting it.
680
+ *
681
+ * Takes the same body a run takes, minus the `quoteId`, and answers a
682
+ * ceiling (`maxCredits`), a `breakdown` to show, and the
683
+ * `normalizedInputHash` admission re-checks. It reserves nothing and spends
684
+ * nothing — a quote is a price, not a purchase.
685
+ */
686
+ quotePro(params) {
687
+ return this.client.request("POST", "/v1/pro-3d-render/quote", { body: params });
688
+ }
689
+ /**
690
+ * Submit a quoted 3D Render Pro run.
691
+ *
692
+ * Requires the `quoteId` from {@link quotePro}: no run starts at a price
693
+ * nobody showed. Sends an `Idempotency-Key` — a fresh one per call unless you
694
+ * supply your own, which you should when retrying a call that timed out.
695
+ *
696
+ * Availability is a property of the deployment: `capabilities().pro` says
697
+ * whether this install can serve it, and which controls you may offer.
698
+ */
699
+ runPro(params, options) {
700
+ return this.client.nodes.run("pro-3d-render", params, {
701
+ idempotencyKey: options?.idempotencyKey ?? newIdempotencyKey()
702
+ });
703
+ }
704
+ /**
705
+ * Quote if needed, run, and wait — the whole operation in one call.
706
+ *
707
+ * Two HTTP requests at most, still ONE paid job: when `quoteId` is absent
708
+ * this quotes the identical body first, so the run is admitted against a
709
+ * hash of exactly what was priced. Pass a `quoteId` to run against a quote
710
+ * you already showed the user.
711
+ *
712
+ * Resolves with the settled result — `videoUrl` (the MP4) and `scenePlan`
713
+ * (the exact composition it was rendered from), plus the revision, poster,
714
+ * validation and renderer metadata. Re-render that same `scenePlan` later
715
+ * with {@link render}, or with a `{kind:'scene'}` source; that costs no
716
+ * authoring.
717
+ */
718
+ async renderProAndWait(params, options) {
719
+ const quoteId = typeof params.quoteId === "string" ? params.quoteId : (await this.quotePro(params)).quoteId;
720
+ return this.client.nodes.runAndWait("pro-3d-render", { ...params, quoteId }, {
721
+ ...options,
722
+ idempotencyKey: options?.idempotencyKey ?? newIdempotencyKey()
723
+ });
724
+ }
652
725
  /** Uses the supplied immutable revision; never starts authoring or a rebuild. */
653
726
  render(params) {
654
727
  return this.client.nodes.run("render-video", params);
@@ -3090,7 +3163,7 @@ var WorkspacesResource = class {
3090
3163
  return this.client.requestText("GET", `/v1/workspaces/${encodeURIComponent(id)}/usage`, { query: { ...opts, format: "csv" } });
3091
3164
  }
3092
3165
  };
3093
- var SDK_VERSION = "2.1.0" ;
3166
+ var SDK_VERSION = "2.2.0" ;
3094
3167
  var CLIENT_HEADER = "X-Nodaro-Client";
3095
3168
  var isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
3096
3169
  var NodaroClient = class _NodaroClient {