@ceki/sdk 1.11.0 → 1.11.2
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 +24 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +14 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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].schedule_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(scheduleId, opts?) -> Browser`
|
|
57
57
|
|
|
58
|
-
Rent a browser by
|
|
58
|
+
Rent a browser by schedule 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(scheduleId);
|
|
119
119
|
|
|
120
120
|
// Explicit profile
|
|
121
|
-
const browser = await client.rent(
|
|
121
|
+
const browser = await client.rent(scheduleId, { human: 'careful' });
|
|
122
122
|
|
|
123
123
|
// Disable humanization
|
|
124
|
-
const browser = await client.rent(
|
|
124
|
+
const browser = await client.rent(scheduleId, { 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
|
+
SCHEDULE=$(ceki search --limit 1 | jq -r '.[0].schedule_id')
|
|
172
|
+
SID=$(ceki rent --schedule $SCHEDULE | 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 --schedule 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,6 +563,7 @@ function keymapForChar(char) {
|
|
|
563
563
|
var Browser = class _Browser {
|
|
564
564
|
sessionId;
|
|
565
565
|
browserId;
|
|
566
|
+
scheduleId;
|
|
566
567
|
chatTopicId;
|
|
567
568
|
browserInfo;
|
|
568
569
|
providerUserId;
|
|
@@ -608,7 +609,8 @@ var Browser = class _Browser {
|
|
|
608
609
|
constructor(client, match, humanizer) {
|
|
609
610
|
this._client = client;
|
|
610
611
|
this.sessionId = match.session_id;
|
|
611
|
-
this.browserId = match.
|
|
612
|
+
this.browserId = match.schedule_id;
|
|
613
|
+
this.scheduleId = match.schedule_id;
|
|
612
614
|
this.chatTopicId = match.chat_topic_id ?? null;
|
|
613
615
|
this.browserInfo = match.browser_info ?? {};
|
|
614
616
|
this.providerUserId = match.provider_user_id ?? null;
|
|
@@ -623,7 +625,7 @@ var Browser = class _Browser {
|
|
|
623
625
|
saveSession(this.sessionId, {
|
|
624
626
|
session_id: this.sessionId,
|
|
625
627
|
chat_topic_id: this.chatTopicId,
|
|
626
|
-
|
|
628
|
+
schedule_id: this.scheduleId,
|
|
627
629
|
last_seen_ts: this._lastSeenTs
|
|
628
630
|
});
|
|
629
631
|
}
|
|
@@ -1392,7 +1394,7 @@ var Client = class _Client {
|
|
|
1392
1394
|
_pongTimer = null;
|
|
1393
1395
|
_lastPongAt = 0;
|
|
1394
1396
|
_pendingRents = /* @__PURE__ */ new Map();
|
|
1395
|
-
// keyed by `rent:<
|
|
1397
|
+
// keyed by `rent:<scheduleId>` or eventId
|
|
1396
1398
|
_pendingResumes = /* @__PURE__ */ new Map();
|
|
1397
1399
|
// keyed by sessionId
|
|
1398
1400
|
_connectResolve = null;
|
|
@@ -1483,18 +1485,18 @@ var Client = class _Client {
|
|
|
1483
1485
|
const items = body.browsers ?? body.data ?? body;
|
|
1484
1486
|
return Array.isArray(items) ? items : [];
|
|
1485
1487
|
}
|
|
1486
|
-
async rent(
|
|
1487
|
-
const rentMsg = { type: "rent", browser_id:
|
|
1488
|
+
async rent(scheduleId, opts) {
|
|
1489
|
+
const rentMsg = { type: "rent", browser_id: scheduleId };
|
|
1488
1490
|
if (opts?.mode) rentMsg.mode = opts.mode;
|
|
1489
1491
|
this._wsSend(rentMsg);
|
|
1490
|
-
const key = `rent:${
|
|
1492
|
+
const key = `rent:${scheduleId}`;
|
|
1491
1493
|
return new Promise((resolve2, reject) => {
|
|
1492
1494
|
const timer = setTimeout(() => {
|
|
1493
1495
|
this._pendingRents.delete(key);
|
|
1494
1496
|
reject(new TimeoutError("Rent timed out after 90s"));
|
|
1495
1497
|
}, 9e4);
|
|
1496
1498
|
this._pendingRents.set(key, {
|
|
1497
|
-
|
|
1499
|
+
scheduleId,
|
|
1498
1500
|
eventId: null,
|
|
1499
1501
|
opts,
|
|
1500
1502
|
resolve: (match) => {
|
|
@@ -1799,7 +1801,7 @@ var Client = class _Client {
|
|
|
1799
1801
|
}
|
|
1800
1802
|
_onMatch(msg) {
|
|
1801
1803
|
const eventId = String(msg.event_id ?? "");
|
|
1802
|
-
const
|
|
1804
|
+
const scheduleId = Number(msg.schedule_id ?? 0);
|
|
1803
1805
|
const sessionId = String(msg.session_id ?? "");
|
|
1804
1806
|
if (msg.requires_ack) {
|
|
1805
1807
|
try {
|
|
@@ -1809,15 +1811,15 @@ var Client = class _Client {
|
|
|
1809
1811
|
}
|
|
1810
1812
|
let pending = this._pendingRents.get(`event:${eventId}`);
|
|
1811
1813
|
if (!pending) {
|
|
1812
|
-
pending = this._pendingRents.get(`rent:${
|
|
1814
|
+
pending = this._pendingRents.get(`rent:${scheduleId}`);
|
|
1813
1815
|
}
|
|
1814
1816
|
if (pending) {
|
|
1815
1817
|
clearTimeout(pending.timer);
|
|
1816
|
-
const key = pending.eventId ? `event:${pending.eventId}` : `rent:${pending.
|
|
1818
|
+
const key = pending.eventId ? `event:${pending.eventId}` : `rent:${pending.scheduleId}`;
|
|
1817
1819
|
this._pendingRents.delete(key);
|
|
1818
1820
|
const match = {
|
|
1819
1821
|
session_id: sessionId,
|
|
1820
|
-
|
|
1822
|
+
schedule_id: scheduleId,
|
|
1821
1823
|
event_id: eventId || null,
|
|
1822
1824
|
chat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,
|
|
1823
1825
|
provider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,
|
|
@@ -1859,7 +1861,7 @@ var Client = class _Client {
|
|
|
1859
1861
|
const match = {
|
|
1860
1862
|
session_id: sessionId,
|
|
1861
1863
|
event_id: msg.event_id != null ? String(msg.event_id) : null,
|
|
1862
|
-
|
|
1864
|
+
schedule_id: Number(msg.schedule_id ?? 0),
|
|
1863
1865
|
chat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,
|
|
1864
1866
|
provider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,
|
|
1865
1867
|
started_at: Date.now(),
|
|
@@ -2014,11 +2016,11 @@ function parseBool(val) {
|
|
|
2014
2016
|
return val === "true" || val === "1" || val === "yes";
|
|
2015
2017
|
}
|
|
2016
2018
|
async function cmdRent(args) {
|
|
2017
|
-
let
|
|
2019
|
+
let scheduleId = null;
|
|
2018
2020
|
let fingerprintFrom = null;
|
|
2019
2021
|
let mode = "incognito";
|
|
2020
2022
|
for (let i = 0; i < args.length; i++) {
|
|
2021
|
-
if (args[i] === "--
|
|
2023
|
+
if (args[i] === "--schedule" && args[i + 1]) scheduleId = parseInt(args[++i], 10);
|
|
2022
2024
|
if (args[i] === "--fingerprint-from" && args[i + 1]) fingerprintFrom = args[++i];
|
|
2023
2025
|
if (args[i] === "--mode" && args[i + 1]) {
|
|
2024
2026
|
const v = args[++i];
|
|
@@ -2029,8 +2031,8 @@ async function cmdRent(args) {
|
|
|
2029
2031
|
mode = v;
|
|
2030
2032
|
}
|
|
2031
2033
|
}
|
|
2032
|
-
if (
|
|
2033
|
-
err("--
|
|
2034
|
+
if (scheduleId == null) {
|
|
2035
|
+
err("--schedule is required", "args");
|
|
2034
2036
|
process.exit(1);
|
|
2035
2037
|
}
|
|
2036
2038
|
const apiKey = getApiKey();
|
|
@@ -2041,17 +2043,17 @@ async function cmdRent(args) {
|
|
|
2041
2043
|
}
|
|
2042
2044
|
const client = await connect(apiKey, connectOptions());
|
|
2043
2045
|
try {
|
|
2044
|
-
const browser = await client.rent(
|
|
2046
|
+
const browser = await client.rent(scheduleId, { human: null, fingerprint: fpData, mode });
|
|
2045
2047
|
saveSession(browser.sessionId, {
|
|
2046
2048
|
session_id: browser.sessionId,
|
|
2047
2049
|
chat_topic_id: browser.chatTopicId,
|
|
2048
|
-
|
|
2050
|
+
schedule_id: browser.scheduleId,
|
|
2049
2051
|
last_seen_ts: null
|
|
2050
2052
|
});
|
|
2051
2053
|
out({
|
|
2052
2054
|
session_id: browser.sessionId,
|
|
2053
2055
|
chat_topic_id: browser.chatTopicId,
|
|
2054
|
-
|
|
2056
|
+
schedule_id: browser.scheduleId
|
|
2055
2057
|
});
|
|
2056
2058
|
} finally {
|
|
2057
2059
|
await closeClient(client);
|
|
@@ -2096,7 +2098,7 @@ async function cmdSessions(args) {
|
|
|
2096
2098
|
process.stdout.write("No sessions found.\n");
|
|
2097
2099
|
return;
|
|
2098
2100
|
}
|
|
2099
|
-
const header = "SID".padEnd(8) + "
|
|
2101
|
+
const header = "SID".padEnd(8) + "SCHEDULE".padEnd(10) + "STARTED".padEnd(22) + "DURATION".padEnd(10) + "EARNED".padEnd(9) + "STATUS".padEnd(10) + "RENTER".padEnd(16) + "PROVIDER";
|
|
2100
2102
|
process.stdout.write(header + "\n");
|
|
2101
2103
|
for (const s of results) {
|
|
2102
2104
|
const started = s.started_at ?? "\u2014";
|
|
@@ -2106,7 +2108,7 @@ async function cmdSessions(args) {
|
|
|
2106
2108
|
const earned = `$${s.earned.toFixed(2)}`;
|
|
2107
2109
|
const renter = s.renter?.name ?? "\u2014";
|
|
2108
2110
|
const provider = s.provider?.name ?? "\u2014";
|
|
2109
|
-
const line = String(s.id).padEnd(8) + String(s.
|
|
2111
|
+
const line = String(s.id).padEnd(8) + String(s.schedule_id).padEnd(10) + started.padEnd(22) + dur.padEnd(10) + earned.padEnd(9) + s.status.padEnd(10) + renter.padEnd(16) + provider;
|
|
2110
2112
|
process.stdout.write(line + "\n");
|
|
2111
2113
|
}
|
|
2112
2114
|
}
|
|
@@ -2529,7 +2531,7 @@ function printHelp() {
|
|
|
2529
2531
|
Usage: ceki <command> [options]
|
|
2530
2532
|
|
|
2531
2533
|
Commands:
|
|
2532
|
-
rent --
|
|
2534
|
+
rent --schedule N [--fingerprint-from PATH]
|
|
2533
2535
|
my-browsers
|
|
2534
2536
|
search [--limit N] [--filter k=v]...
|
|
2535
2537
|
snapshot <sid> -o PATH
|