@ceki/sdk 1.10.0 → 1.11.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 +9 -9
- package/dist/cli.js +22 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +12 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -5
- package/dist/index.d.ts +4 -5
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ import { connect } from '@ceki/sdk';
|
|
|
21
21
|
|
|
22
22
|
const client = await connect(process.env.CEKI_API_KEY!);
|
|
23
23
|
const options = await client.search({ geo: 'US', language: 'en' });
|
|
24
|
-
const browser = await client.rent(options[0].
|
|
24
|
+
const browser = await client.rent(options[0].browser_id);
|
|
25
25
|
|
|
26
26
|
await browser.navigate('https://example.com');
|
|
27
27
|
const snap = await browser.snapshot();
|
|
@@ -53,9 +53,9 @@ Establish a WebSocket connection to the relay. Returns a `Client` instance.
|
|
|
53
53
|
|
|
54
54
|
Search for available browsers. Filters: `geo`, `language`, etc.
|
|
55
55
|
|
|
56
|
-
### `client.rent(
|
|
56
|
+
### `client.rent(browserId, opts?) -> Browser`
|
|
57
57
|
|
|
58
|
-
Rent a browser by
|
|
58
|
+
Rent a browser by browser ID. Waits up to 60s for a match. Options:
|
|
59
59
|
- `human` — `'natural'` (default), `'careful'`, or `null` (no humanization)
|
|
60
60
|
- `maskingMode` — enable masking
|
|
61
61
|
- `fingerprint` — `true`, `false`, or fingerprint object
|
|
@@ -115,13 +115,13 @@ Browser actions include human-like timing by default — delays before/after act
|
|
|
115
115
|
|
|
116
116
|
```typescript
|
|
117
117
|
// Default: natural profile (enabled by default)
|
|
118
|
-
const browser = await client.rent(
|
|
118
|
+
const browser = await client.rent(browserId);
|
|
119
119
|
|
|
120
120
|
// Explicit profile
|
|
121
|
-
const browser = await client.rent(
|
|
121
|
+
const browser = await client.rent(browserId, { human: 'careful' });
|
|
122
122
|
|
|
123
123
|
// Disable humanization
|
|
124
|
-
const browser = await client.rent(
|
|
124
|
+
const browser = await client.rent(browserId, { human: null });
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
### Environment overrides
|
|
@@ -168,8 +168,8 @@ npm install -g @ceki/sdk
|
|
|
168
168
|
```bash
|
|
169
169
|
export CEKI_API_KEY=ag_...
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
SID=$(ceki rent --
|
|
171
|
+
BROWSER=$(ceki search --limit 1 | jq -r '.[0].browser_id')
|
|
172
|
+
SID=$(ceki rent --browser $BROWSER | jq -r .session_id)
|
|
173
173
|
ceki navigate $SID https://example.com
|
|
174
174
|
ceki snapshot $SID -o snap.png
|
|
175
175
|
ceki stop $SID
|
|
@@ -185,7 +185,7 @@ The CLI persists session state locally — after `rent` it saves the session ID
|
|
|
185
185
|
|---|---|
|
|
186
186
|
| `search [--limit N] [--filter K=V]…` | List available browsers |
|
|
187
187
|
| `my-browsers` | List browsers with pre-arranged rent contracts |
|
|
188
|
-
| `rent --
|
|
188
|
+
| `rent --browser ID [--mode incognito\|main] [--fingerprint-from FILE]` | Rent a browser |
|
|
189
189
|
| `sessions [--all] [--limit N] [--json]` | List your sessions |
|
|
190
190
|
| `stop SID` | End a session |
|
|
191
191
|
| `wait SID` | Block until the session ends |
|
package/dist/cli.js
CHANGED
|
@@ -563,7 +563,6 @@ function keymapForChar(char) {
|
|
|
563
563
|
var Browser = class _Browser {
|
|
564
564
|
sessionId;
|
|
565
565
|
browserId;
|
|
566
|
-
scheduleId;
|
|
567
566
|
chatTopicId;
|
|
568
567
|
browserInfo;
|
|
569
568
|
providerUserId;
|
|
@@ -609,8 +608,7 @@ var Browser = class _Browser {
|
|
|
609
608
|
constructor(client, match, humanizer) {
|
|
610
609
|
this._client = client;
|
|
611
610
|
this.sessionId = match.session_id;
|
|
612
|
-
this.browserId = match.
|
|
613
|
-
this.scheduleId = match.schedule_id;
|
|
611
|
+
this.browserId = match.browser_id;
|
|
614
612
|
this.chatTopicId = match.chat_topic_id ?? null;
|
|
615
613
|
this.browserInfo = match.browser_info ?? {};
|
|
616
614
|
this.providerUserId = match.provider_user_id ?? null;
|
|
@@ -625,7 +623,7 @@ var Browser = class _Browser {
|
|
|
625
623
|
saveSession(this.sessionId, {
|
|
626
624
|
session_id: this.sessionId,
|
|
627
625
|
chat_topic_id: this.chatTopicId,
|
|
628
|
-
|
|
626
|
+
browser_id: this.browserId,
|
|
629
627
|
last_seen_ts: this._lastSeenTs
|
|
630
628
|
});
|
|
631
629
|
}
|
|
@@ -1394,7 +1392,7 @@ var Client = class _Client {
|
|
|
1394
1392
|
_pongTimer = null;
|
|
1395
1393
|
_lastPongAt = 0;
|
|
1396
1394
|
_pendingRents = /* @__PURE__ */ new Map();
|
|
1397
|
-
// keyed by `rent:<
|
|
1395
|
+
// keyed by `rent:<browserId>` or eventId
|
|
1398
1396
|
_pendingResumes = /* @__PURE__ */ new Map();
|
|
1399
1397
|
// keyed by sessionId
|
|
1400
1398
|
_connectResolve = null;
|
|
@@ -1485,18 +1483,18 @@ var Client = class _Client {
|
|
|
1485
1483
|
const items = body.browsers ?? body.data ?? body;
|
|
1486
1484
|
return Array.isArray(items) ? items : [];
|
|
1487
1485
|
}
|
|
1488
|
-
async rent(
|
|
1489
|
-
const rentMsg = { type: "rent", browser_id:
|
|
1486
|
+
async rent(browserId, opts) {
|
|
1487
|
+
const rentMsg = { type: "rent", browser_id: browserId };
|
|
1490
1488
|
if (opts?.mode) rentMsg.mode = opts.mode;
|
|
1491
1489
|
this._wsSend(rentMsg);
|
|
1492
|
-
const key = `rent:${
|
|
1490
|
+
const key = `rent:${browserId}`;
|
|
1493
1491
|
return new Promise((resolve2, reject) => {
|
|
1494
1492
|
const timer = setTimeout(() => {
|
|
1495
1493
|
this._pendingRents.delete(key);
|
|
1496
1494
|
reject(new TimeoutError("Rent timed out after 90s"));
|
|
1497
1495
|
}, 9e4);
|
|
1498
1496
|
this._pendingRents.set(key, {
|
|
1499
|
-
|
|
1497
|
+
browserId,
|
|
1500
1498
|
eventId: null,
|
|
1501
1499
|
opts,
|
|
1502
1500
|
resolve: (match) => {
|
|
@@ -1801,7 +1799,7 @@ var Client = class _Client {
|
|
|
1801
1799
|
}
|
|
1802
1800
|
_onMatch(msg) {
|
|
1803
1801
|
const eventId = String(msg.event_id ?? "");
|
|
1804
|
-
const
|
|
1802
|
+
const browserId = Number(msg.browser_id ?? 0);
|
|
1805
1803
|
const sessionId = String(msg.session_id ?? "");
|
|
1806
1804
|
if (msg.requires_ack) {
|
|
1807
1805
|
try {
|
|
@@ -1811,15 +1809,15 @@ var Client = class _Client {
|
|
|
1811
1809
|
}
|
|
1812
1810
|
let pending = this._pendingRents.get(`event:${eventId}`);
|
|
1813
1811
|
if (!pending) {
|
|
1814
|
-
pending = this._pendingRents.get(`rent:${
|
|
1812
|
+
pending = this._pendingRents.get(`rent:${browserId}`);
|
|
1815
1813
|
}
|
|
1816
1814
|
if (pending) {
|
|
1817
1815
|
clearTimeout(pending.timer);
|
|
1818
|
-
const key = pending.eventId ? `event:${pending.eventId}` : `rent:${pending.
|
|
1816
|
+
const key = pending.eventId ? `event:${pending.eventId}` : `rent:${pending.browserId}`;
|
|
1819
1817
|
this._pendingRents.delete(key);
|
|
1820
1818
|
const match = {
|
|
1821
1819
|
session_id: sessionId,
|
|
1822
|
-
|
|
1820
|
+
browser_id: browserId,
|
|
1823
1821
|
event_id: eventId || null,
|
|
1824
1822
|
chat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,
|
|
1825
1823
|
provider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,
|
|
@@ -1861,7 +1859,7 @@ var Client = class _Client {
|
|
|
1861
1859
|
const match = {
|
|
1862
1860
|
session_id: sessionId,
|
|
1863
1861
|
event_id: msg.event_id != null ? String(msg.event_id) : null,
|
|
1864
|
-
|
|
1862
|
+
browser_id: Number(msg.browser_id ?? 0),
|
|
1865
1863
|
chat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,
|
|
1866
1864
|
provider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,
|
|
1867
1865
|
started_at: Date.now(),
|
|
@@ -2016,11 +2014,11 @@ function parseBool(val) {
|
|
|
2016
2014
|
return val === "true" || val === "1" || val === "yes";
|
|
2017
2015
|
}
|
|
2018
2016
|
async function cmdRent(args) {
|
|
2019
|
-
let
|
|
2017
|
+
let browserId = null;
|
|
2020
2018
|
let fingerprintFrom = null;
|
|
2021
2019
|
let mode = "incognito";
|
|
2022
2020
|
for (let i = 0; i < args.length; i++) {
|
|
2023
|
-
if (args[i] === "--
|
|
2021
|
+
if (args[i] === "--browser" && args[i + 1]) browserId = parseInt(args[++i], 10);
|
|
2024
2022
|
if (args[i] === "--fingerprint-from" && args[i + 1]) fingerprintFrom = args[++i];
|
|
2025
2023
|
if (args[i] === "--mode" && args[i + 1]) {
|
|
2026
2024
|
const v = args[++i];
|
|
@@ -2031,8 +2029,8 @@ async function cmdRent(args) {
|
|
|
2031
2029
|
mode = v;
|
|
2032
2030
|
}
|
|
2033
2031
|
}
|
|
2034
|
-
if (
|
|
2035
|
-
err("--
|
|
2032
|
+
if (browserId == null) {
|
|
2033
|
+
err("--browser is required", "args");
|
|
2036
2034
|
process.exit(1);
|
|
2037
2035
|
}
|
|
2038
2036
|
const apiKey = getApiKey();
|
|
@@ -2043,17 +2041,17 @@ async function cmdRent(args) {
|
|
|
2043
2041
|
}
|
|
2044
2042
|
const client = await connect(apiKey, connectOptions());
|
|
2045
2043
|
try {
|
|
2046
|
-
const browser = await client.rent(
|
|
2044
|
+
const browser = await client.rent(browserId, { human: null, fingerprint: fpData, mode });
|
|
2047
2045
|
saveSession(browser.sessionId, {
|
|
2048
2046
|
session_id: browser.sessionId,
|
|
2049
2047
|
chat_topic_id: browser.chatTopicId,
|
|
2050
|
-
|
|
2048
|
+
browser_id: browser.browserId,
|
|
2051
2049
|
last_seen_ts: null
|
|
2052
2050
|
});
|
|
2053
2051
|
out({
|
|
2054
2052
|
session_id: browser.sessionId,
|
|
2055
2053
|
chat_topic_id: browser.chatTopicId,
|
|
2056
|
-
|
|
2054
|
+
browser_id: browser.browserId
|
|
2057
2055
|
});
|
|
2058
2056
|
} finally {
|
|
2059
2057
|
await closeClient(client);
|
|
@@ -2098,7 +2096,7 @@ async function cmdSessions(args) {
|
|
|
2098
2096
|
process.stdout.write("No sessions found.\n");
|
|
2099
2097
|
return;
|
|
2100
2098
|
}
|
|
2101
|
-
const header = "SID".padEnd(8) + "
|
|
2099
|
+
const header = "SID".padEnd(8) + "BROWSER".padEnd(10) + "STARTED".padEnd(22) + "DURATION".padEnd(10) + "EARNED".padEnd(9) + "STATUS".padEnd(10) + "RENTER".padEnd(16) + "PROVIDER";
|
|
2102
2100
|
process.stdout.write(header + "\n");
|
|
2103
2101
|
for (const s of results) {
|
|
2104
2102
|
const started = s.started_at ?? "\u2014";
|
|
@@ -2108,7 +2106,7 @@ async function cmdSessions(args) {
|
|
|
2108
2106
|
const earned = `$${s.earned.toFixed(2)}`;
|
|
2109
2107
|
const renter = s.renter?.name ?? "\u2014";
|
|
2110
2108
|
const provider = s.provider?.name ?? "\u2014";
|
|
2111
|
-
const line = String(s.id).padEnd(8) + String(s.
|
|
2109
|
+
const line = String(s.id).padEnd(8) + String(s.browser_id).padEnd(10) + started.padEnd(22) + dur.padEnd(10) + earned.padEnd(9) + s.status.padEnd(10) + renter.padEnd(16) + provider;
|
|
2112
2110
|
process.stdout.write(line + "\n");
|
|
2113
2111
|
}
|
|
2114
2112
|
}
|
|
@@ -2531,7 +2529,7 @@ function printHelp() {
|
|
|
2531
2529
|
Usage: ceki <command> [options]
|
|
2532
2530
|
|
|
2533
2531
|
Commands:
|
|
2534
|
-
rent --
|
|
2532
|
+
rent --browser N [--fingerprint-from PATH]
|
|
2535
2533
|
my-browsers
|
|
2536
2534
|
search [--limit N] [--filter k=v]...
|
|
2537
2535
|
snapshot <sid> -o PATH
|