@scalebrowser/sdk 0.4.1 → 0.5.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 +352 -5
- package/dist/index.d.cts +883 -8
- package/dist/index.d.ts +883 -8
- package/dist/index.js +352 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,13 @@ var ErrorCode = {
|
|
|
31
31
|
* Distinct from ConcurrencyLimit (4008 = the plan is full, buy more or free any
|
|
32
32
|
* browser): the caller's move here costs nothing. Close it on that machine, or
|
|
33
33
|
* take it over from the app running there. */
|
|
34
|
-
ProfileInUse: 4012
|
|
34
|
+
ProfileInUse: 4012,
|
|
35
|
+
/** The exit address this start drew belongs to another profile (DEC-017).
|
|
36
|
+
* Distinct from ProxyGeo (4002 = wrong country or wrong kind of exit, so change
|
|
37
|
+
* the proxy): here the proxy is fine and the address is simply spoken for. Wait
|
|
38
|
+
* for a term to run out, let the daemon draw again, or turn exclusivity off for
|
|
39
|
+
* this profile. */
|
|
40
|
+
ExitAddressTaken: 4013
|
|
35
41
|
};
|
|
36
42
|
var CODE_LABELS = {
|
|
37
43
|
4001: "Not found",
|
|
@@ -43,7 +49,8 @@ var CODE_LABELS = {
|
|
|
43
49
|
4008: "Concurrent-browser limit reached (subscription-wide)",
|
|
44
50
|
4010: "Unauthorized",
|
|
45
51
|
4011: "No account connected to this machine",
|
|
46
|
-
4012: "This profile is open on another machine"
|
|
52
|
+
4012: "This profile is open on another machine",
|
|
53
|
+
4013: "This exit address belongs to another profile"
|
|
47
54
|
};
|
|
48
55
|
var ScalebrowserError = class extends Error {
|
|
49
56
|
constructor(message) {
|
|
@@ -254,7 +261,7 @@ var ControlApi = class extends ClientCore {
|
|
|
254
261
|
/**
|
|
255
262
|
* Hand the daemon a file so `interact action=upload` has something to attach.
|
|
256
263
|
*
|
|
257
|
-
* The bytes are bound to the PROFILE, not to a
|
|
264
|
+
* The bytes are bound to the PROFILE, not to a lease: set a file up
|
|
258
265
|
* before leasing, and a lease released mid-task does not destroy it.
|
|
259
266
|
*/
|
|
260
267
|
putArtifact(profileId, bytes, name) {
|
|
@@ -572,6 +579,83 @@ var IdentityApi = class extends ClientCore {
|
|
|
572
579
|
}
|
|
573
580
|
};
|
|
574
581
|
|
|
582
|
+
// src/client-tasks.ts
|
|
583
|
+
var TasksApi = class extends ClientCore {
|
|
584
|
+
// -- Tasks ------------------------------------------------------------------
|
|
585
|
+
//
|
|
586
|
+
// Fleet-wide by default, and deliberately so: the question this surface exists
|
|
587
|
+
// for is "what is outstanding across my twenty accounts", and a per-profile
|
|
588
|
+
// route would make a client ask it twenty times and sort the answers itself.
|
|
589
|
+
//
|
|
590
|
+
// None of these starts a browser. A task is a row, so reading the whole fleet's
|
|
591
|
+
// list costs nothing from the plan's concurrent-browser allowance. Reserve only
|
|
592
|
+
// the profiles that turn out to have work.
|
|
593
|
+
/**
|
|
594
|
+
* What is still to be done. No filter means every task of every profile.
|
|
595
|
+
*
|
|
596
|
+
* Pass `state: 'open'` for what is outstanding; without it, tasks finished
|
|
597
|
+
* within the last day are included too.
|
|
598
|
+
*/
|
|
599
|
+
listTasks(params, signal) {
|
|
600
|
+
return this.request("GET", "/v1/tasks", void 0, {
|
|
601
|
+
query: { ...params },
|
|
602
|
+
signal
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Put the same task on one or many profiles, one row each.
|
|
607
|
+
*
|
|
608
|
+
* A task is a LINE, not a document: name the work and leave the material where
|
|
609
|
+
* it lives. `due_at` is a deadline, not a trigger; nothing runs by itself.
|
|
610
|
+
*
|
|
611
|
+
* Profiles that no longer exist come back in `missing` instead of failing the
|
|
612
|
+
* whole call.
|
|
613
|
+
*/
|
|
614
|
+
createTasks(body) {
|
|
615
|
+
return this.request("POST", "/v1/tasks", body);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Call a task off.
|
|
619
|
+
*
|
|
620
|
+
* Only a task nobody has claimed can be cancelled here. One an agent is working
|
|
621
|
+
* on right now is stopped by telling that agent, which is a channel that already
|
|
622
|
+
* reaches it; this surface answers `409` for it rather than pretending.
|
|
623
|
+
*/
|
|
624
|
+
cancelTask(id) {
|
|
625
|
+
return this.request("PATCH", `/v1/tasks/${enc(id)}`, { state: "cancelled" });
|
|
626
|
+
}
|
|
627
|
+
/** Remove a task outright. */
|
|
628
|
+
deleteTask(id) {
|
|
629
|
+
return this.request("DELETE", `/v1/tasks/${enc(id)}`);
|
|
630
|
+
}
|
|
631
|
+
// -- Profile memory ---------------------------------------------------------
|
|
632
|
+
/**
|
|
633
|
+
* A profile's durable memory, the `PROFILE.md` at the top of its directory.
|
|
634
|
+
*
|
|
635
|
+
* `content` is `null` while nobody has written one: a profile starts with no
|
|
636
|
+
* file, not with an empty one.
|
|
637
|
+
*/
|
|
638
|
+
getProfileMemory(profileId, signal) {
|
|
639
|
+
return this.request("GET", `/v1/profiles/${enc(profileId)}/memory`, void 0, {
|
|
640
|
+
signal
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Replace a profile's memory.
|
|
645
|
+
*
|
|
646
|
+
* Stored verbatim: no trimming, no appended newline, no line-ending
|
|
647
|
+
* translation. The last write wins and nothing warns, exactly as with a file
|
|
648
|
+
* two people can open.
|
|
649
|
+
*/
|
|
650
|
+
putProfileMemory(profileId, content) {
|
|
651
|
+
return this.request("PUT", `/v1/profiles/${enc(profileId)}/memory`, { content });
|
|
652
|
+
}
|
|
653
|
+
/** Remove a profile's memory. Removing one that is not there is not an error. */
|
|
654
|
+
deleteProfileMemory(profileId) {
|
|
655
|
+
return this.request("DELETE", `/v1/profiles/${enc(profileId)}/memory`);
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
|
|
575
659
|
// src/client-runs.ts
|
|
576
660
|
var RunsApi = class extends ClientCore {
|
|
577
661
|
// ── Agent runs ─────────────────────────────────────────────────────────────
|
|
@@ -608,6 +692,205 @@ var RunsApi = class extends ClientCore {
|
|
|
608
692
|
}
|
|
609
693
|
};
|
|
610
694
|
|
|
695
|
+
// src/client-videos.ts
|
|
696
|
+
var VideosApi = class extends ClientCore {
|
|
697
|
+
// ── Videos ────────────────────────────────────────────────────────────────
|
|
698
|
+
/** One gallery page, newest first. Running renders are videos too. */
|
|
699
|
+
listVideos(params = {}, signal) {
|
|
700
|
+
return this.request("GET", "/v1/videos", void 0, {
|
|
701
|
+
query: {
|
|
702
|
+
q: params.q,
|
|
703
|
+
profile_id: params.profile_id,
|
|
704
|
+
run_id: params.run_id,
|
|
705
|
+
kind: params.kind,
|
|
706
|
+
preset: params.preset,
|
|
707
|
+
state: params.state,
|
|
708
|
+
page: params.page
|
|
709
|
+
},
|
|
710
|
+
signal
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/** One video row, progress included while it renders. */
|
|
714
|
+
getVideo(videoId, signal) {
|
|
715
|
+
return this.request("GET", `/v1/videos/${enc(videoId)}`, void 0, { signal });
|
|
716
|
+
}
|
|
717
|
+
/** Rename. The title also lands in the MP4's metadata on the NEXT render. */
|
|
718
|
+
renameVideo(videoId, title, signal) {
|
|
719
|
+
return this.request("PATCH", `/v1/videos/${enc(videoId)}`, { title }, { signal });
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Delete a video (`raw: true` also purges its recording's raw material).
|
|
723
|
+
* A live share link is revoked first; 409 `job_running` while it renders.
|
|
724
|
+
*/
|
|
725
|
+
deleteVideo(videoId, opts = {}, signal) {
|
|
726
|
+
return this.request("DELETE", `/v1/videos/${enc(videoId)}`, void 0, {
|
|
727
|
+
query: { raw: opts.raw },
|
|
728
|
+
signal
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
/** Cancel a queued or rendering video. `done` stays done (409). */
|
|
732
|
+
cancelVideo(videoId, signal) {
|
|
733
|
+
return this.request("POST", `/v1/videos/${enc(videoId)}/cancel`, void 0, {
|
|
734
|
+
signal
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
/** Render a failed or cancelled video again: same id, new job. */
|
|
738
|
+
rerenderVideo(videoId, body = {}, signal) {
|
|
739
|
+
return this.request("POST", `/v1/videos/${enc(videoId)}/renders`, body, { signal });
|
|
740
|
+
}
|
|
741
|
+
/** A short-lived fetchable address for one asset (default the video). */
|
|
742
|
+
videoAccess(videoId, asset, signal) {
|
|
743
|
+
return this.request(
|
|
744
|
+
"POST",
|
|
745
|
+
`/v1/videos/${enc(videoId)}/access`,
|
|
746
|
+
asset ? { asset } : {},
|
|
747
|
+
{ signal }
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
/** One asset's bytes, through a freshly minted grant. */
|
|
751
|
+
async downloadVideoFile(videoId, asset = "video", signal) {
|
|
752
|
+
const grant = await this.videoAccess(videoId, asset, signal);
|
|
753
|
+
const grantParam = new URL(grant.url, "http://x").searchParams.get("grant") ?? "";
|
|
754
|
+
return this.requestBytes("GET", `/v1/videos/${enc(videoId)}/file`, {
|
|
755
|
+
query: { asset, grant: grantParam },
|
|
756
|
+
signal
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
/** What recordings and videos cost on disk, plus the caps. */
|
|
760
|
+
videosStorage(signal) {
|
|
761
|
+
return this.request("GET", "/v1/videos/storage", void 0, { signal });
|
|
762
|
+
}
|
|
763
|
+
// ── Recordings ────────────────────────────────────────────────────────────
|
|
764
|
+
/** Recordings, newest first. The row outlives its raw bytes. */
|
|
765
|
+
listRecordings(params = {}, signal) {
|
|
766
|
+
return this.request("GET", "/v1/recordings", void 0, {
|
|
767
|
+
query: { profile_id: params.profile_id },
|
|
768
|
+
signal
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
getRecording(recordingId, signal) {
|
|
772
|
+
return this.request("GET", `/v1/recordings/${enc(recordingId)}`, void 0, {
|
|
773
|
+
signal
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Purge a recording's RAW material; the row stays forever
|
|
778
|
+
* (`raw_purged_at`). 409 `job_running` while a render of it is open.
|
|
779
|
+
*/
|
|
780
|
+
deleteRecordingRaw(recordingId, signal) {
|
|
781
|
+
return this.request("DELETE", `/v1/recordings/${enc(recordingId)}`, void 0, {
|
|
782
|
+
signal
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
/** A NEW video from this recording (the same body the `video` tool takes). */
|
|
786
|
+
renderRecording(recordingId, body = {}, signal) {
|
|
787
|
+
return this.request("POST", `/v1/recordings/${enc(recordingId)}/renders`, body, {
|
|
788
|
+
signal
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
// ── Codecs ────────────────────────────────────────────────────────────────
|
|
792
|
+
/** What this machine can encode with. The hardware list is PROBED, not read
|
|
793
|
+
* off the binary: `h264_nvenc` is always listed and fails without a driver. */
|
|
794
|
+
getCodecs(signal) {
|
|
795
|
+
return this.request("GET", "/v1/codecs", void 0, { signal });
|
|
796
|
+
}
|
|
797
|
+
/** Turn Cisco's OpenH264 on or off. The hardware encoders are not switchable. */
|
|
798
|
+
setCodecEnabled(codec, enabled, signal) {
|
|
799
|
+
return this.request("PUT", `/v1/codecs/${enc(codec)}`, { enabled }, { signal });
|
|
800
|
+
}
|
|
801
|
+
// -- Sharing ----------------------------------------------------------------
|
|
802
|
+
/** Make a finished video public. Measures every file, asks the control plane
|
|
803
|
+
* for permission, uploads, and has the result confirmed. */
|
|
804
|
+
share(videoId, body = {}, signal) {
|
|
805
|
+
return this.request("POST", `/v1/videos/${enc(videoId)}/share`, body, {
|
|
806
|
+
signal
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
/** The share ORDER as this machine knows it. How many people watched and
|
|
810
|
+
* whether the link still lives is read from the control plane, not from
|
|
811
|
+
* here: a number carried along would be wrong the moment another machine
|
|
812
|
+
* revoked. */
|
|
813
|
+
shareStatus(videoId, signal) {
|
|
814
|
+
return this.request(
|
|
815
|
+
"GET",
|
|
816
|
+
`/v1/videos/${enc(videoId)}/share`,
|
|
817
|
+
void 0,
|
|
818
|
+
{ signal }
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
/** Revoke the link. The files fall at once; the order stays until the control
|
|
822
|
+
* plane confirms. */
|
|
823
|
+
revokeShare(videoId, signal) {
|
|
824
|
+
return this.request("DELETE", `/v1/videos/${enc(videoId)}/share`, void 0, {
|
|
825
|
+
signal
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
// -- Media ------------------------------------------------------------------
|
|
829
|
+
/** Files a preset points at: background image, music bed, subtitle font. */
|
|
830
|
+
listMedia(kind, signal) {
|
|
831
|
+
return this.request("GET", "/v1/media", void 0, {
|
|
832
|
+
query: { kind },
|
|
833
|
+
signal
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
/** Upload one file. The body IS the file; `name` and `mime` ride in the query. */
|
|
837
|
+
uploadMedia(kind, name, mime, bytes, signal) {
|
|
838
|
+
return this.request("POST", "/v1/media", bytes, {
|
|
839
|
+
query: { kind, name, mime },
|
|
840
|
+
signal
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
/** Remove a file. Refuses with 409 while a preset still points at it. */
|
|
844
|
+
deleteMedia(id, signal) {
|
|
845
|
+
return this.request("DELETE", `/v1/media/${enc(id)}`, void 0, { signal });
|
|
846
|
+
}
|
|
847
|
+
/** The file itself. */
|
|
848
|
+
mediaFile(id, signal) {
|
|
849
|
+
return this.requestBytes("GET", `/v1/media/${enc(id)}/file`, { signal });
|
|
850
|
+
}
|
|
851
|
+
// -- Voice providers --------------------------------------------------------
|
|
852
|
+
/** Which speech providers have a key. The key itself never comes back: the
|
|
853
|
+
* answer carries a hint, and that is on purpose. */
|
|
854
|
+
listTtsProviders(signal) {
|
|
855
|
+
return this.request("GET", "/v1/tts-providers", void 0, { signal });
|
|
856
|
+
}
|
|
857
|
+
/** Store a key, or rename one. Leaving `apiKey` out keeps the stored key.
|
|
858
|
+
*
|
|
859
|
+
* `apiKey` may also be a secret reference (`{{sb:...}}`), which is what an
|
|
860
|
+
* agent gets back after fetching a key from the provider's own site: it is
|
|
861
|
+
* not allowed to read the value. A reference needs `profileId`, because the
|
|
862
|
+
* value belongs to one profile and there is nothing to open without it.
|
|
863
|
+
*/
|
|
864
|
+
putTtsProvider(provider, body, signal) {
|
|
865
|
+
return this.request(
|
|
866
|
+
"PUT",
|
|
867
|
+
`/v1/tts-providers/${enc(provider)}`,
|
|
868
|
+
{ api_key: body.apiKey, label: body.label, profile_id: body.profileId },
|
|
869
|
+
{ signal }
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
/** Call the provider once for real, and record that the key works.
|
|
873
|
+
*
|
|
874
|
+
* Costs one short sentence of the account's own quota. Until this runs, a
|
|
875
|
+
* provider row says `verified_at: null`, which means untested rather than
|
|
876
|
+
* broken.
|
|
877
|
+
*/
|
|
878
|
+
verifyTtsProvider(provider, signal) {
|
|
879
|
+
return this.request(
|
|
880
|
+
"POST",
|
|
881
|
+
`/v1/tts-providers/${enc(provider)}/verify`,
|
|
882
|
+
void 0,
|
|
883
|
+
{ signal }
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
/** Forget a provider's key. */
|
|
887
|
+
deleteTtsProvider(provider, signal) {
|
|
888
|
+
return this.request("DELETE", `/v1/tts-providers/${enc(provider)}`, void 0, {
|
|
889
|
+
signal
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
|
|
611
894
|
// src/events.ts
|
|
612
895
|
var MAX_BACKOFF_MS = 15e3;
|
|
613
896
|
function subscribeEvents(params, handlers) {
|
|
@@ -1111,6 +1394,15 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1111
1394
|
stopProfile(id) {
|
|
1112
1395
|
return this.request("POST", `/v1/profiles/${enc(id)}/stop`, {});
|
|
1113
1396
|
}
|
|
1397
|
+
/** Drop the profile's lease, the operator's way out.
|
|
1398
|
+
*
|
|
1399
|
+
* An agent releases with its handle; this call needs none. The daemon stops
|
|
1400
|
+
* the browser first when one is still up, then lets the lease go, so a dead
|
|
1401
|
+
* session cannot park the profile until its TTL runs out. `released: false`
|
|
1402
|
+
* is an honest no-op: there was nothing to let go. */
|
|
1403
|
+
releaseProfile(id) {
|
|
1404
|
+
return this.request("POST", `/v1/profiles/${enc(id)}/release`, {});
|
|
1405
|
+
}
|
|
1114
1406
|
/** Ask for a profile that is open on another machine of this account.
|
|
1115
1407
|
*
|
|
1116
1408
|
* Closes nothing here and nothing there: the control plane revokes the holder's
|
|
@@ -1182,6 +1474,42 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1182
1474
|
deletePreset(id) {
|
|
1183
1475
|
return this.request("DELETE", `/v1/presets/${enc(id)}`);
|
|
1184
1476
|
}
|
|
1477
|
+
// ── Video presets ──────────────────────────────────────────────────────────
|
|
1478
|
+
listVideoPresets(signal) {
|
|
1479
|
+
return this.request("GET", "/v1/video-presets", void 0, { signal });
|
|
1480
|
+
}
|
|
1481
|
+
getVideoPreset(id, signal) {
|
|
1482
|
+
return this.request("GET", `/v1/video-presets/${enc(id)}`, void 0, { signal });
|
|
1483
|
+
}
|
|
1484
|
+
/** The daemon validates `config` strictly and names the failing field path. */
|
|
1485
|
+
createVideoPreset(body) {
|
|
1486
|
+
return this.request("POST", "/v1/video-presets", body);
|
|
1487
|
+
}
|
|
1488
|
+
/** A built-in preset refuses edits. Duplicate it and edit the copy. */
|
|
1489
|
+
updateVideoPreset(id, body) {
|
|
1490
|
+
return this.request("PATCH", `/v1/video-presets/${enc(id)}`, body);
|
|
1491
|
+
}
|
|
1492
|
+
/** The only way to make a built-in preset yours: copy, then edit the copy. */
|
|
1493
|
+
duplicateVideoPreset(id, body = {}) {
|
|
1494
|
+
return this.request("POST", `/v1/video-presets/${enc(id)}/duplicate`, body);
|
|
1495
|
+
}
|
|
1496
|
+
deleteVideoPreset(id) {
|
|
1497
|
+
return this.request("DELETE", `/v1/video-presets/${enc(id)}`);
|
|
1498
|
+
}
|
|
1499
|
+
/** One still of the sample film under an UNSAVED config, drawn by the daemon's own renderer.
|
|
1500
|
+
* `moment` wins over `frame`; both absent means the daemon's default moment. */
|
|
1501
|
+
previewVideoPreset(body, signal) {
|
|
1502
|
+
return this.request("POST", "/v1/video-presets/preview", body, { signal });
|
|
1503
|
+
}
|
|
1504
|
+
/** A clip of the sample film, blocking until it is encoded (the editor uses the SSE form of the
|
|
1505
|
+
* same route; a script waits). Fetch the bytes with `downloadVideoPresetClip`. */
|
|
1506
|
+
previewVideoPresetClip(body, signal) {
|
|
1507
|
+
return this.request("POST", "/v1/video-presets/preview/clip", body, { signal });
|
|
1508
|
+
}
|
|
1509
|
+
/** The clip's MP4 bytes. */
|
|
1510
|
+
downloadVideoPresetClip(id, signal) {
|
|
1511
|
+
return this.requestBytes("GET", `/v1/video-presets/preview/clip/${enc(id)}`, { signal });
|
|
1512
|
+
}
|
|
1185
1513
|
/**
|
|
1186
1514
|
* The values a preset's `constraints` may take. Ask rather than hardcode: the
|
|
1187
1515
|
* region list comes from the daemon's embedded persona model, so a pinned copy
|
|
@@ -1238,6 +1566,18 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1238
1566
|
signal
|
|
1239
1567
|
});
|
|
1240
1568
|
}
|
|
1569
|
+
// ── Exit-address exclusivity (DEC-017) ──────────────────────────────────────
|
|
1570
|
+
/** Which exit addresses this profile owns, and how far the rule reaches.
|
|
1571
|
+
*
|
|
1572
|
+
* `scope` is `'machine'` while this computer has no account key. That is the
|
|
1573
|
+
* ordinary state of a second machine until sync is unlocked there once, and it is
|
|
1574
|
+
* reported rather than hidden: believing the rule spans three machines when it
|
|
1575
|
+
* spans one is worse than knowing. */
|
|
1576
|
+
getExitStatus(profileId, signal) {
|
|
1577
|
+
return this.request("GET", `/v1/profiles/${enc(profileId)}/exit`, void 0, {
|
|
1578
|
+
signal
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1241
1581
|
// ── Session bundles (AC-ST-002/003) ─────────────────────────────────────────
|
|
1242
1582
|
exportSession(profileId, body) {
|
|
1243
1583
|
return this.request("POST", `/v1/profiles/${enc(profileId)}/session/export`, body);
|
|
@@ -1317,7 +1657,14 @@ function deriveMetricsFromProfiles(profiles) {
|
|
|
1317
1657
|
profiles: []
|
|
1318
1658
|
};
|
|
1319
1659
|
}
|
|
1320
|
-
applyMixins(ScalebrowserClient, [
|
|
1660
|
+
applyMixins(ScalebrowserClient, [
|
|
1661
|
+
IdentityApi,
|
|
1662
|
+
RunsApi,
|
|
1663
|
+
VideosApi,
|
|
1664
|
+
ControlApi,
|
|
1665
|
+
ExtensionsApi,
|
|
1666
|
+
TasksApi
|
|
1667
|
+
]);
|
|
1321
1668
|
|
|
1322
1669
|
// src/types.ts
|
|
1323
1670
|
var RUNTIME_STATES = ["stopped", "starting", "running", "crashed"];
|
|
@@ -1327,7 +1674,7 @@ var PROXY_KINDS = ["http", "socks5", "gateway"];
|
|
|
1327
1674
|
var ROTATIONS = ["sticky", "rotating"];
|
|
1328
1675
|
|
|
1329
1676
|
// src/index.ts
|
|
1330
|
-
var VERSION = "0.
|
|
1677
|
+
var VERSION = "0.5.0";
|
|
1331
1678
|
|
|
1332
1679
|
exports.ApiError = ApiError;
|
|
1333
1680
|
exports.CdpError = CdpError;
|