scavio 0.13.0 → 0.14.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 +54 -11
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -10
- package/dist/index.d.ts +18 -10
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,16 +33,31 @@ const client = new Scavio({
|
|
|
33
33
|
baseUrl: "https://api.scavio.dev", // default
|
|
34
34
|
timeout: 30_000, // ms, default
|
|
35
35
|
maxRequestsPerSecond: 1, // 1-10, default 1
|
|
36
|
+
maxRetries: 2, // default 2, set 0 to disable
|
|
36
37
|
});
|
|
37
38
|
```
|
|
38
39
|
|
|
40
|
+
`maxRetries` is the number of extra attempts after the first request, applied
|
|
41
|
+
only to transient failures — HTTP 429, 500, 502, 503, 504 and network or timeout
|
|
42
|
+
errors. Backoff is exponential with full jitter, capped at 8s, and a
|
|
43
|
+
`Retry-After` header is honored when the API sends one. Non-transient errors
|
|
44
|
+
(400, 401, 402, 404) are never retried.
|
|
45
|
+
|
|
46
|
+
`maxRequestsPerSecond` throttles the client so it never sends more than N
|
|
47
|
+
requests in any one-second window. Your plan also has a server-side concurrency
|
|
48
|
+
limit on simultaneous in-flight requests: 1 on free and pay-as-you-go, 2 on
|
|
49
|
+
Project, 3 on Bootstrap, 5 on Startup, 10 on Growth.
|
|
50
|
+
|
|
39
51
|
## API Reference
|
|
40
52
|
|
|
41
53
|
### Google
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
passthrough); each costs 1 credit.
|
|
45
|
-
|
|
55
|
+
Each method hits its own `/api/v2/google*` endpoint and returns Google's full
|
|
56
|
+
response (raw passthrough); each costs 1 credit. Results come back as
|
|
57
|
+
`organic_results[]` with `link` and `snippet`. Geo and paging use `gl`, `hl`,
|
|
58
|
+
`start`, `google_domain` and `device` — the old v1 vocabulary (`light_request`,
|
|
59
|
+
`country_code`, `language`, `search_type`, `page`) does not exist on v2 and is
|
|
60
|
+
dropped server-side.
|
|
46
61
|
|
|
47
62
|
```typescript
|
|
48
63
|
// SERP search (includes the AI Overview when Google shows one)
|
|
@@ -129,6 +144,9 @@ await client.walmart.product({
|
|
|
129
144
|
|
|
130
145
|
### YouTube
|
|
131
146
|
|
|
147
|
+
Credit cost varies by endpoint: `transcript` costs 8; `streams` costs 3;
|
|
148
|
+
`search` and `shorts` cost 2; every other YouTube endpoint costs 1.
|
|
149
|
+
|
|
132
150
|
```typescript
|
|
133
151
|
// Search videos
|
|
134
152
|
await client.youtube.search({
|
|
@@ -176,6 +194,14 @@ await client.youtube.channelResolve({ channel: "@mkbhd" }); // handle/URL -> id
|
|
|
176
194
|
|
|
177
195
|
### Reddit
|
|
178
196
|
|
|
197
|
+
Every Reddit endpoint costs 1 credit.
|
|
198
|
+
|
|
199
|
+
`search()` takes only `query` and `cursor` — there is no result-type or sort
|
|
200
|
+
filter upstream, so anything else is dropped server-side. It returns
|
|
201
|
+
`data.results` with `next_cursor` and `has_more`. `post()` returns a flat post
|
|
202
|
+
object under `data` and carries no comments; use `postComments()` for those.
|
|
203
|
+
The subreddit and user feeds return `data.posts`.
|
|
204
|
+
|
|
179
205
|
```typescript
|
|
180
206
|
// Search posts
|
|
181
207
|
await client.reddit.search({ query: "typescript", cursor: "..." });
|
|
@@ -262,9 +288,11 @@ Credit cost varies by endpoint: `job` costs 30; `personPosts`, `companyPosts`,
|
|
|
262
288
|
> `searchPosts`. They remain callable but always return HTTP 410 and are never
|
|
263
289
|
> billed. `company()` returns `featured_employees` (a small sample of staff), and
|
|
264
290
|
> `searchJobs()` with a company name substitutes for `companyJobs()`.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
291
|
+
|
|
292
|
+
`personPosts`, `companyPosts` and `searchJobs` paginate: pass the previous
|
|
293
|
+
response's `next_cursor` as `cursor` to fetch the next page. `personPosts` also
|
|
294
|
+
takes `type` (`"posts"`, `"comments"` or `"reactions"`) to pick the feed.
|
|
295
|
+
`postComments` pages with a 1-based `page` instead.
|
|
268
296
|
|
|
269
297
|
### TikTok
|
|
270
298
|
|
|
@@ -284,8 +312,8 @@ await client.tiktok.videoComments({ video_id: "vid123", count: 20 });
|
|
|
284
312
|
// Comment replies
|
|
285
313
|
await client.tiktok.commentReplies({ video_id: "vid123", comment_id: "c456" });
|
|
286
314
|
|
|
287
|
-
// Search videos
|
|
288
|
-
await client.tiktok.searchVideos({ keyword: "dance", sort_type: "
|
|
315
|
+
// Search videos (sort_type: '0' = relevance, '1' = most likes)
|
|
316
|
+
await client.tiktok.searchVideos({ keyword: "dance", sort_type: "1" });
|
|
289
317
|
|
|
290
318
|
// Search users
|
|
291
319
|
await client.tiktok.searchUsers({ keyword: "cooking" });
|
|
@@ -364,8 +392,16 @@ await client.tiktokShop.resolve({ url: "https://vt.tiktok.com/ZT2AHoGsE/" });
|
|
|
364
392
|
|
|
365
393
|
### Instagram
|
|
366
394
|
|
|
367
|
-
Credit cost varies by endpoint
|
|
368
|
-
|
|
395
|
+
Credit cost varies by endpoint, in three tiers:
|
|
396
|
+
|
|
397
|
+
| Credits | Methods |
|
|
398
|
+
|---|---|
|
|
399
|
+
| 2 | `userPosts` |
|
|
400
|
+
| 8 | `post`, `commentReplies` |
|
|
401
|
+
| 10 | `profile`, `userReels`, `userTagged`, `userStories`, `postComments`, `searchUsers`, `searchHashtags`, `userFollowers`, `userFollowings` |
|
|
402
|
+
|
|
403
|
+
The 10-credit endpoints run two upstream providers in parallel and bill both
|
|
404
|
+
legs; the 8-credit ones have no fallback leg to hedge against.
|
|
369
405
|
|
|
370
406
|
```typescript
|
|
371
407
|
// User profile
|
|
@@ -422,12 +458,19 @@ All error classes:
|
|
|
422
458
|
| Class | HTTP Status | Description |
|
|
423
459
|
|-------|------------|-------------|
|
|
424
460
|
| `MissingAPIKeyError` | — | No API key provided |
|
|
461
|
+
| `ScavioConnectionError` | — | Request never reached the API (DNS, reset, TLS) |
|
|
462
|
+
| `ScavioTimeoutError` | — | Request exceeded the configured `timeout` |
|
|
463
|
+
| `BadRequestError` | 400 | Invalid request parameters |
|
|
425
464
|
| `InvalidAPIKeyError` | 401 | Invalid API key |
|
|
426
465
|
| `InsufficientCreditsError` | 402 | No credits remaining |
|
|
427
|
-
| `
|
|
466
|
+
| `NotFoundError` | 404 | No data upstream for that id (see TikTok Shop above) |
|
|
428
467
|
| `RateLimitError` | 429 | Rate limit exceeded |
|
|
429
468
|
| `ScavioAPIError` | other | Catch-all (has `.statusCode`) |
|
|
430
469
|
|
|
470
|
+
Every class extends `ScavioError`, so `catch (e) { if (e instanceof ScavioError) }`
|
|
471
|
+
matches all of them. All except `MissingAPIKeyError`, `ScavioConnectionError` and
|
|
472
|
+
`ScavioTimeoutError` carry `.statusCode` and `.responseBody`.
|
|
473
|
+
|
|
431
474
|
## Runtime Support
|
|
432
475
|
|
|
433
476
|
- Node.js 18+
|
package/dist/index.cjs
CHANGED
|
@@ -398,12 +398,17 @@ var RedditNamespace = class {
|
|
|
398
398
|
this.client = client;
|
|
399
399
|
}
|
|
400
400
|
client;
|
|
401
|
+
/** Returns `data.results` plus `next_cursor` / `has_more` (not `data.posts`). */
|
|
401
402
|
async search(options) {
|
|
402
403
|
return this.client._post("/api/v1/reddit/search", options);
|
|
403
404
|
}
|
|
404
405
|
async searchSuggestions(options) {
|
|
405
406
|
return this.client._post("/api/v1/reddit/search/suggestions", options);
|
|
406
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Returns a flat post object under `data` (post_id, title, text, url,
|
|
410
|
+
* subreddit, author, score, ...). Comments are a separate call.
|
|
411
|
+
*/
|
|
407
412
|
async post(options) {
|
|
408
413
|
return this.client._post("/api/v1/reddit/post", options);
|
|
409
414
|
}
|