scavio 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Scavio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,204 @@
1
+ # Scavio
2
+
3
+ TypeScript SDK for the [Scavio Search API](https://scavio.dev) — real-time Google, Amazon, Walmart, YouTube, Reddit, and TikTok data.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install scavio
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { Scavio } from "scavio";
15
+
16
+ const client = new Scavio({ apiKey: "sk_..." });
17
+
18
+ // Google search
19
+ const results = await client.search({ query: "web scraping api" });
20
+
21
+ // Amazon product lookup
22
+ const product = await client.amazon.product({ asin: "B09V3KXJPB" });
23
+
24
+ // Check usage
25
+ const usage = await client.getUsage();
26
+ ```
27
+
28
+ ## Configuration
29
+
30
+ ```typescript
31
+ const client = new Scavio({
32
+ apiKey: "sk_...", // or set SCAVIO_API_KEY env var
33
+ baseUrl: "https://api.scavio.dev", // default
34
+ timeout: 30_000, // ms, default
35
+ maxRequestsPerSecond: 1, // 1-10, default 1
36
+ });
37
+ ```
38
+
39
+ ## API Reference
40
+
41
+ ### Google
42
+
43
+ ```typescript
44
+ await client.google.search({
45
+ query: "web scraping",
46
+ country_code: "us", // optional
47
+ language: "en", // optional
48
+ page: 1, // optional
49
+ search_type: "news", // optional
50
+ device: "desktop", // optional
51
+ nfpr: false, // optional — no auto-correct
52
+ light_request: false, // optional
53
+ });
54
+ ```
55
+
56
+ ### Amazon
57
+
58
+ ```typescript
59
+ // Search products
60
+ await client.amazon.search({
61
+ query: "laptop",
62
+ domain: "amazon.com", // optional
63
+ country: "us", // optional
64
+ sort_by: "price_asc", // optional
65
+ pages: 1, // optional
66
+ });
67
+
68
+ // Get product by ASIN
69
+ await client.amazon.product({
70
+ asin: "B09V3KXJPB",
71
+ domain: "amazon.com", // optional
72
+ });
73
+ ```
74
+
75
+ ### Walmart
76
+
77
+ ```typescript
78
+ // Search products
79
+ await client.walmart.search({
80
+ query: "tv",
81
+ min_price: 100, // optional
82
+ max_price: 500, // optional
83
+ });
84
+
85
+ // Get product by ID
86
+ await client.walmart.product({
87
+ product_id: "123456",
88
+ });
89
+ ```
90
+
91
+ ### YouTube
92
+
93
+ ```typescript
94
+ // Search videos
95
+ await client.youtube.search({
96
+ query: "typescript tutorial",
97
+ upload_date: "week", // optional
98
+ sort_by: "relevance", // optional
99
+ hd: true, // optional
100
+ });
101
+
102
+ // Get video metadata
103
+ await client.youtube.metadata({
104
+ video_id: "dQw4w9WgXcQ",
105
+ });
106
+ ```
107
+
108
+ ### Reddit
109
+
110
+ ```typescript
111
+ // Search posts
112
+ await client.reddit.search({
113
+ query: "typescript",
114
+ sort: "relevance", // optional
115
+ type: "link", // optional
116
+ });
117
+
118
+ // Get specific post
119
+ await client.reddit.post({
120
+ url: "https://reddit.com/r/typescript/comments/abc123",
121
+ });
122
+ ```
123
+
124
+ ### TikTok
125
+
126
+ ```typescript
127
+ // User profile
128
+ await client.tiktok.profile({ username: "testuser" });
129
+
130
+ // User posts
131
+ await client.tiktok.userPosts({ sec_user_id: "abc123", count: 30 });
132
+
133
+ // Video details
134
+ await client.tiktok.video({ video_id: "vid123" });
135
+
136
+ // Video comments
137
+ await client.tiktok.videoComments({ video_id: "vid123", count: 20 });
138
+
139
+ // Comment replies
140
+ await client.tiktok.commentReplies({ video_id: "vid123", comment_id: "c456" });
141
+
142
+ // Search videos
143
+ await client.tiktok.searchVideos({ keyword: "dance", sort_type: "likes" });
144
+
145
+ // Search users
146
+ await client.tiktok.searchUsers({ keyword: "cooking" });
147
+
148
+ // Hashtag info
149
+ await client.tiktok.hashtag({ hashtag_name: "fyp" });
150
+
151
+ // Hashtag videos
152
+ await client.tiktok.hashtagVideos({ hashtag_id: "h789", count: 30 });
153
+
154
+ // User followers
155
+ await client.tiktok.userFollowers({ sec_user_id: "abc123" });
156
+
157
+ // User followings
158
+ await client.tiktok.userFollowings({ sec_user_id: "abc123" });
159
+ ```
160
+
161
+ ### Usage
162
+
163
+ ```typescript
164
+ const usage = await client.getUsage();
165
+ ```
166
+
167
+ ## Error Handling
168
+
169
+ ```typescript
170
+ import { Scavio, InvalidAPIKeyError, RateLimitError } from "scavio";
171
+
172
+ try {
173
+ const results = await client.search({ query: "test" });
174
+ } catch (error) {
175
+ if (error instanceof InvalidAPIKeyError) {
176
+ // 401 — bad API key
177
+ } else if (error instanceof RateLimitError) {
178
+ // 429 — too many requests
179
+ }
180
+ }
181
+ ```
182
+
183
+ All error classes:
184
+
185
+ | Class | HTTP Status | Description |
186
+ |-------|------------|-------------|
187
+ | `MissingAPIKeyError` | — | No API key provided |
188
+ | `InvalidAPIKeyError` | 401 | Invalid API key |
189
+ | `InsufficientCreditsError` | 402 | No credits remaining |
190
+ | `BadRequestError` | 400 | Invalid request parameters |
191
+ | `RateLimitError` | 429 | Rate limit exceeded |
192
+ | `ScavioAPIError` | other | Catch-all (has `.statusCode`) |
193
+
194
+ ## Runtime Support
195
+
196
+ - Node.js 18+
197
+ - Deno
198
+ - Bun
199
+
200
+ Zero dependencies — uses native `fetch`.
201
+
202
+ ## License
203
+
204
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,363 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BadRequestError: () => BadRequestError,
24
+ InsufficientCreditsError: () => InsufficientCreditsError,
25
+ InvalidAPIKeyError: () => InvalidAPIKeyError,
26
+ MissingAPIKeyError: () => MissingAPIKeyError,
27
+ RateLimitError: () => RateLimitError,
28
+ Scavio: () => Scavio,
29
+ ScavioAPIError: () => ScavioAPIError,
30
+ ScavioError: () => ScavioError
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/errors.ts
35
+ var ScavioError = class extends Error {
36
+ constructor(message) {
37
+ super(message);
38
+ this.name = "ScavioError";
39
+ }
40
+ };
41
+ var MissingAPIKeyError = class extends ScavioError {
42
+ constructor() {
43
+ super(
44
+ "No API key provided. Pass apiKey or set the SCAVIO_API_KEY environment variable. Get your free key at https://dashboard.scavio.dev"
45
+ );
46
+ this.name = "MissingAPIKeyError";
47
+ }
48
+ };
49
+ var InvalidAPIKeyError = class extends ScavioError {
50
+ constructor(message = "Invalid API key") {
51
+ super(message);
52
+ this.name = "InvalidAPIKeyError";
53
+ }
54
+ };
55
+ var InsufficientCreditsError = class extends ScavioError {
56
+ constructor(message = "Insufficient credits") {
57
+ super(message);
58
+ this.name = "InsufficientCreditsError";
59
+ }
60
+ };
61
+ var BadRequestError = class extends ScavioError {
62
+ constructor(message = "Bad request") {
63
+ super(message);
64
+ this.name = "BadRequestError";
65
+ }
66
+ };
67
+ var RateLimitError = class extends ScavioError {
68
+ constructor(message = "Rate limit exceeded") {
69
+ super(message);
70
+ this.name = "RateLimitError";
71
+ }
72
+ };
73
+ var ScavioAPIError = class extends ScavioError {
74
+ statusCode;
75
+ constructor(statusCode, message) {
76
+ super(`API error ${statusCode}: ${message}`);
77
+ this.name = "ScavioAPIError";
78
+ this.statusCode = statusCode;
79
+ }
80
+ };
81
+
82
+ // src/http.ts
83
+ var BASE_URL = "https://api.scavio.dev";
84
+ var DEFAULT_TIMEOUT = 3e4;
85
+ function buildHeaders(apiKey) {
86
+ return {
87
+ Authorization: `Bearer ${apiKey}`,
88
+ "Content-Type": "application/json",
89
+ "X-Client-Source": "scavio-js"
90
+ };
91
+ }
92
+ function stripUndefined(obj) {
93
+ const result = {};
94
+ for (const [key, value] of Object.entries(obj)) {
95
+ if (value !== void 0) {
96
+ result[key] = value;
97
+ }
98
+ }
99
+ return result;
100
+ }
101
+ function handleError(statusCode, body) {
102
+ let error = body.error ?? "Unknown error";
103
+ if (typeof error === "object" && error !== null && "message" in error) {
104
+ error = error.message;
105
+ }
106
+ const msg = String(error);
107
+ if (statusCode === 400) throw new BadRequestError(msg);
108
+ if (statusCode === 401) throw new InvalidAPIKeyError(msg);
109
+ if (statusCode === 402) throw new InsufficientCreditsError(msg);
110
+ if (statusCode === 429) throw new RateLimitError(msg);
111
+ throw new ScavioAPIError(statusCode, msg);
112
+ }
113
+ async function request(options) {
114
+ await options.rateLimiter.wait();
115
+ const url = `${options.baseUrl}${options.path}`;
116
+ const headers = buildHeaders(options.apiKey);
117
+ const controller = new AbortController();
118
+ const timeoutId = setTimeout(() => controller.abort(), options.timeout);
119
+ try {
120
+ const fetchOptions = {
121
+ method: options.method,
122
+ headers,
123
+ signal: controller.signal
124
+ };
125
+ if (options.method === "POST" && options.body) {
126
+ fetchOptions.body = JSON.stringify(stripUndefined(options.body));
127
+ }
128
+ const response = await fetch(url, fetchOptions);
129
+ if (!response.ok) {
130
+ let body = {};
131
+ try {
132
+ body = await response.json();
133
+ } catch {
134
+ }
135
+ handleError(response.status, body);
136
+ }
137
+ return await response.json();
138
+ } finally {
139
+ clearTimeout(timeoutId);
140
+ }
141
+ }
142
+
143
+ // src/rate-limiter.ts
144
+ var RateLimiter = class {
145
+ maxPerSecond;
146
+ timestamps = [];
147
+ pending = Promise.resolve();
148
+ constructor(maxPerSecond) {
149
+ this.maxPerSecond = maxPerSecond;
150
+ }
151
+ async wait() {
152
+ const ticket = this.pending.then(() => this.acquire());
153
+ this.pending = ticket;
154
+ return ticket;
155
+ }
156
+ async acquire() {
157
+ this.cleanup();
158
+ if (this.timestamps.length >= this.maxPerSecond) {
159
+ const sleepMs = 1e3 - (Date.now() - this.timestamps[0]);
160
+ if (sleepMs > 0) {
161
+ await new Promise((resolve) => setTimeout(resolve, sleepMs));
162
+ }
163
+ this.cleanup();
164
+ }
165
+ this.timestamps.push(Date.now());
166
+ }
167
+ cleanup() {
168
+ const now = Date.now();
169
+ while (this.timestamps.length > 0 && now - this.timestamps[0] >= 1e3) {
170
+ this.timestamps.shift();
171
+ }
172
+ }
173
+ };
174
+
175
+ // src/namespaces/amazon.ts
176
+ var AmazonNamespace = class {
177
+ constructor(client) {
178
+ this.client = client;
179
+ }
180
+ client;
181
+ async search(options) {
182
+ return this.client._post("/api/v1/amazon/search", options);
183
+ }
184
+ async product(options) {
185
+ const { asin, ...rest } = options;
186
+ return this.client._post("/api/v1/amazon/product", {
187
+ query: asin,
188
+ ...rest
189
+ });
190
+ }
191
+ };
192
+
193
+ // src/namespaces/google.ts
194
+ var GoogleNamespace = class {
195
+ constructor(client) {
196
+ this.client = client;
197
+ }
198
+ client;
199
+ async search(options) {
200
+ return this.client._post("/api/v1/google", options);
201
+ }
202
+ };
203
+
204
+ // src/namespaces/reddit.ts
205
+ var RedditNamespace = class {
206
+ constructor(client) {
207
+ this.client = client;
208
+ }
209
+ client;
210
+ async search(options) {
211
+ return this.client._post("/api/v1/reddit/search", options);
212
+ }
213
+ async post(options) {
214
+ return this.client._post("/api/v1/reddit/post", options);
215
+ }
216
+ };
217
+
218
+ // src/namespaces/tiktok.ts
219
+ var TikTokNamespace = class {
220
+ constructor(client) {
221
+ this.client = client;
222
+ }
223
+ client;
224
+ async profile(options) {
225
+ return this.client._post("/api/v1/tiktok/profile", options);
226
+ }
227
+ async userPosts(options) {
228
+ return this.client._post("/api/v1/tiktok/user/posts", options);
229
+ }
230
+ async video(options) {
231
+ return this.client._post("/api/v1/tiktok/video", options);
232
+ }
233
+ async videoComments(options) {
234
+ return this.client._post("/api/v1/tiktok/video/comments", options);
235
+ }
236
+ async commentReplies(options) {
237
+ return this.client._post("/api/v1/tiktok/video/comments/replies", options);
238
+ }
239
+ async searchVideos(options) {
240
+ return this.client._post("/api/v1/tiktok/search/videos", options);
241
+ }
242
+ async searchUsers(options) {
243
+ return this.client._post("/api/v1/tiktok/search/users", options);
244
+ }
245
+ async hashtag(options) {
246
+ return this.client._post("/api/v1/tiktok/hashtag", options);
247
+ }
248
+ async hashtagVideos(options) {
249
+ return this.client._post("/api/v1/tiktok/hashtag/videos", options);
250
+ }
251
+ async userFollowers(options) {
252
+ return this.client._post("/api/v1/tiktok/user/followers", options);
253
+ }
254
+ async userFollowings(options) {
255
+ return this.client._post("/api/v1/tiktok/user/followings", options);
256
+ }
257
+ };
258
+
259
+ // src/namespaces/walmart.ts
260
+ var WalmartNamespace = class {
261
+ constructor(client) {
262
+ this.client = client;
263
+ }
264
+ client;
265
+ async search(options) {
266
+ return this.client._post("/api/v1/walmart/search", options);
267
+ }
268
+ async product(options) {
269
+ return this.client._post("/api/v1/walmart/product", options);
270
+ }
271
+ };
272
+
273
+ // src/namespaces/youtube.ts
274
+ var YouTubeNamespace = class {
275
+ constructor(client) {
276
+ this.client = client;
277
+ }
278
+ client;
279
+ async search(options) {
280
+ const { query, ...rest } = options;
281
+ return this.client._post("/api/v1/youtube/search", {
282
+ search: query,
283
+ ...rest
284
+ });
285
+ }
286
+ async metadata(options) {
287
+ return this.client._post("/api/v1/youtube/metadata", options);
288
+ }
289
+ };
290
+
291
+ // src/client.ts
292
+ var Scavio = class {
293
+ google;
294
+ amazon;
295
+ walmart;
296
+ youtube;
297
+ reddit;
298
+ tiktok;
299
+ apiKey;
300
+ baseUrl;
301
+ timeout;
302
+ rateLimiter;
303
+ constructor(config) {
304
+ this.apiKey = config?.apiKey ?? process.env.SCAVIO_API_KEY ?? "";
305
+ if (!this.apiKey) {
306
+ throw new MissingAPIKeyError();
307
+ }
308
+ this.baseUrl = (config?.baseUrl ?? BASE_URL).replace(/\/+$/, "");
309
+ this.timeout = config?.timeout ?? DEFAULT_TIMEOUT;
310
+ const rps = config?.maxRequestsPerSecond ?? 1;
311
+ if (rps < 1 || rps > 10) {
312
+ throw new ScavioError("maxRequestsPerSecond must be between 1 and 10");
313
+ }
314
+ this.rateLimiter = new RateLimiter(rps);
315
+ this.google = new GoogleNamespace(this);
316
+ this.amazon = new AmazonNamespace(this);
317
+ this.walmart = new WalmartNamespace(this);
318
+ this.youtube = new YouTubeNamespace(this);
319
+ this.reddit = new RedditNamespace(this);
320
+ this.tiktok = new TikTokNamespace(this);
321
+ }
322
+ /** @internal */
323
+ async _post(path, body) {
324
+ return request({
325
+ method: "POST",
326
+ path,
327
+ apiKey: this.apiKey,
328
+ baseUrl: this.baseUrl,
329
+ timeout: this.timeout,
330
+ rateLimiter: this.rateLimiter,
331
+ body
332
+ });
333
+ }
334
+ /** @internal */
335
+ async _get(path) {
336
+ return request({
337
+ method: "GET",
338
+ path,
339
+ apiKey: this.apiKey,
340
+ baseUrl: this.baseUrl,
341
+ timeout: this.timeout,
342
+ rateLimiter: this.rateLimiter
343
+ });
344
+ }
345
+ async search(options) {
346
+ return this.google.search(options);
347
+ }
348
+ async getUsage() {
349
+ return this._get("/api/v1/usage");
350
+ }
351
+ };
352
+ // Annotate the CommonJS export names for ESM import in node:
353
+ 0 && (module.exports = {
354
+ BadRequestError,
355
+ InsufficientCreditsError,
356
+ InvalidAPIKeyError,
357
+ MissingAPIKeyError,
358
+ RateLimitError,
359
+ Scavio,
360
+ ScavioAPIError,
361
+ ScavioError
362
+ });
363
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/rate-limiter.ts","../src/namespaces/amazon.ts","../src/namespaces/google.ts","../src/namespaces/reddit.ts","../src/namespaces/tiktok.ts","../src/namespaces/walmart.ts","../src/namespaces/youtube.ts","../src/client.ts"],"sourcesContent":["export { Scavio } from \"./client.js\";\nexport type { ScavioConfig } from \"./client.js\";\n\nexport {\n ScavioError,\n MissingAPIKeyError,\n InvalidAPIKeyError,\n InsufficientCreditsError,\n BadRequestError,\n RateLimitError,\n ScavioAPIError,\n} from \"./errors.js\";\n\nexport type { GoogleSearchOptions } from \"./namespaces/google.js\";\nexport type {\n AmazonSearchOptions,\n AmazonProductOptions,\n} from \"./namespaces/amazon.js\";\nexport type {\n WalmartSearchOptions,\n WalmartProductOptions,\n} from \"./namespaces/walmart.js\";\nexport type {\n YouTubeSearchOptions,\n YouTubeMetadataOptions,\n} from \"./namespaces/youtube.js\";\nexport type {\n RedditSearchOptions,\n RedditPostOptions,\n} from \"./namespaces/reddit.js\";\nexport type {\n TikTokProfileOptions,\n TikTokUserPostsOptions,\n TikTokVideoOptions,\n TikTokVideoCommentsOptions,\n TikTokCommentRepliesOptions,\n TikTokSearchVideosOptions,\n TikTokSearchUsersOptions,\n TikTokHashtagOptions,\n TikTokHashtagVideosOptions,\n TikTokUserFollowersOptions,\n TikTokUserFollowingsOptions,\n} from \"./namespaces/tiktok.js\";\n","export class ScavioError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ScavioError\";\n }\n}\n\nexport class MissingAPIKeyError extends ScavioError {\n constructor() {\n super(\n \"No API key provided. Pass apiKey or set the SCAVIO_API_KEY \" +\n \"environment variable. Get your free key at https://dashboard.scavio.dev\",\n );\n this.name = \"MissingAPIKeyError\";\n }\n}\n\nexport class InvalidAPIKeyError extends ScavioError {\n constructor(message = \"Invalid API key\") {\n super(message);\n this.name = \"InvalidAPIKeyError\";\n }\n}\n\nexport class InsufficientCreditsError extends ScavioError {\n constructor(message = \"Insufficient credits\") {\n super(message);\n this.name = \"InsufficientCreditsError\";\n }\n}\n\nexport class BadRequestError extends ScavioError {\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"BadRequestError\";\n }\n}\n\nexport class RateLimitError extends ScavioError {\n constructor(message = \"Rate limit exceeded\") {\n super(message);\n this.name = \"RateLimitError\";\n }\n}\n\nexport class ScavioAPIError extends ScavioError {\n public readonly statusCode: number;\n\n constructor(statusCode: number, message: string) {\n super(`API error ${statusCode}: ${message}`);\n this.name = \"ScavioAPIError\";\n this.statusCode = statusCode;\n }\n}\n","import {\n BadRequestError,\n InsufficientCreditsError,\n InvalidAPIKeyError,\n RateLimitError,\n ScavioAPIError,\n} from \"./errors.js\";\nimport type { RateLimiter } from \"./rate-limiter.js\";\n\nexport const BASE_URL = \"https://api.scavio.dev\";\nexport const DEFAULT_TIMEOUT = 30_000;\n\nfunction buildHeaders(apiKey: string): Record<string, string> {\n return {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"X-Client-Source\": \"scavio-js\",\n };\n}\n\nfunction stripUndefined(\n obj: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction handleError(statusCode: number, body: Record<string, unknown>): never {\n let error = body.error ?? \"Unknown error\";\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n error = (error as { message: string }).message;\n }\n const msg = String(error);\n\n if (statusCode === 400) throw new BadRequestError(msg);\n if (statusCode === 401) throw new InvalidAPIKeyError(msg);\n if (statusCode === 402) throw new InsufficientCreditsError(msg);\n if (statusCode === 429) throw new RateLimitError(msg);\n throw new ScavioAPIError(statusCode, msg);\n}\n\nexport async function request(options: {\n method: \"GET\" | \"POST\";\n path: string;\n apiKey: string;\n baseUrl: string;\n timeout: number;\n rateLimiter: RateLimiter;\n body?: Record<string, unknown>;\n}): Promise<Record<string, unknown>> {\n await options.rateLimiter.wait();\n\n const url = `${options.baseUrl}${options.path}`;\n const headers = buildHeaders(options.apiKey);\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), options.timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method: options.method,\n headers,\n signal: controller.signal,\n };\n\n if (options.method === \"POST\" && options.body) {\n fetchOptions.body = JSON.stringify(stripUndefined(options.body));\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n let body: Record<string, unknown> = {};\n try {\n body = (await response.json()) as Record<string, unknown>;\n } catch {\n // ignore parse failures\n }\n handleError(response.status, body);\n }\n\n return (await response.json()) as Record<string, unknown>;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n","export class RateLimiter {\n private readonly maxPerSecond: number;\n private readonly timestamps: number[] = [];\n private pending: Promise<void> = Promise.resolve();\n\n constructor(maxPerSecond: number) {\n this.maxPerSecond = maxPerSecond;\n }\n\n async wait(): Promise<void> {\n const ticket = this.pending.then(() => this.acquire());\n this.pending = ticket;\n return ticket;\n }\n\n private async acquire(): Promise<void> {\n this.cleanup();\n if (this.timestamps.length >= this.maxPerSecond) {\n const sleepMs = 1000 - (Date.now() - this.timestamps[0]!);\n if (sleepMs > 0) {\n await new Promise<void>((resolve) => setTimeout(resolve, sleepMs));\n }\n this.cleanup();\n }\n this.timestamps.push(Date.now());\n }\n\n private cleanup(): void {\n const now = Date.now();\n while (this.timestamps.length > 0 && now - this.timestamps[0]! >= 1000) {\n this.timestamps.shift();\n }\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface AmazonSearchOptions {\n query: string;\n domain?: string;\n country?: string;\n language?: string;\n currency?: string;\n device?: string;\n sort_by?: string;\n start_page?: number;\n pages?: number;\n category_id?: string;\n merchant_id?: string;\n zip_code?: string;\n autoselect_variant?: boolean;\n}\n\nexport interface AmazonProductOptions {\n asin: string;\n domain?: string;\n country?: string;\n language?: string;\n currency?: string;\n device?: string;\n zip_code?: string;\n autoselect_variant?: boolean;\n}\n\nexport class AmazonNamespace {\n constructor(private client: Scavio) {}\n\n async search(\n options: AmazonSearchOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/amazon/search\", options);\n }\n\n async product(\n options: AmazonProductOptions,\n ): Promise<Record<string, unknown>> {\n const { asin, ...rest } = options;\n return this.client._post(\"/api/v1/amazon/product\", {\n query: asin,\n ...rest,\n });\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface GoogleSearchOptions {\n query: string;\n country_code?: string;\n language?: string;\n page?: number;\n search_type?: string;\n device?: string;\n nfpr?: boolean;\n light_request?: boolean;\n}\n\nexport class GoogleNamespace {\n constructor(private client: Scavio) {}\n\n async search(options: GoogleSearchOptions): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/google\", options);\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface RedditSearchOptions {\n query: string;\n type?: string;\n sort?: string;\n cursor?: string;\n}\n\nexport interface RedditPostOptions {\n url: string;\n}\n\nexport class RedditNamespace {\n constructor(private client: Scavio) {}\n\n async search(\n options: RedditSearchOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/reddit/search\", options);\n }\n\n async post(options: RedditPostOptions): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/reddit/post\", options);\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface TikTokProfileOptions {\n username?: string;\n sec_user_id?: string;\n}\n\nexport interface TikTokUserPostsOptions {\n sec_user_id: string;\n cursor?: string;\n count?: number;\n sort_type?: string;\n}\n\nexport interface TikTokVideoOptions {\n video_id: string;\n}\n\nexport interface TikTokVideoCommentsOptions {\n video_id: string;\n cursor?: string;\n count?: number;\n}\n\nexport interface TikTokCommentRepliesOptions {\n video_id: string;\n comment_id: string;\n cursor?: string;\n count?: number;\n}\n\nexport interface TikTokSearchVideosOptions {\n keyword: string;\n cursor?: string;\n count?: number;\n sort_type?: string;\n publish_time?: string;\n}\n\nexport interface TikTokSearchUsersOptions {\n keyword: string;\n cursor?: string;\n count?: number;\n}\n\nexport interface TikTokHashtagOptions {\n hashtag_name?: string;\n hashtag_id?: string;\n}\n\nexport interface TikTokHashtagVideosOptions {\n hashtag_id: string;\n cursor?: string;\n count?: number;\n}\n\nexport interface TikTokUserFollowersOptions {\n sec_user_id: string;\n count?: number;\n page_token?: string;\n min_time?: number;\n}\n\nexport interface TikTokUserFollowingsOptions {\n sec_user_id: string;\n count?: number;\n page_token?: string;\n min_time?: number;\n}\n\nexport class TikTokNamespace {\n constructor(private client: Scavio) {}\n\n async profile(\n options: TikTokProfileOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/profile\", options);\n }\n\n async userPosts(\n options: TikTokUserPostsOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/user/posts\", options);\n }\n\n async video(\n options: TikTokVideoOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/video\", options);\n }\n\n async videoComments(\n options: TikTokVideoCommentsOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/video/comments\", options);\n }\n\n async commentReplies(\n options: TikTokCommentRepliesOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/video/comments/replies\", options);\n }\n\n async searchVideos(\n options: TikTokSearchVideosOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/search/videos\", options);\n }\n\n async searchUsers(\n options: TikTokSearchUsersOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/search/users\", options);\n }\n\n async hashtag(\n options: TikTokHashtagOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/hashtag\", options);\n }\n\n async hashtagVideos(\n options: TikTokHashtagVideosOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/hashtag/videos\", options);\n }\n\n async userFollowers(\n options: TikTokUserFollowersOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/user/followers\", options);\n }\n\n async userFollowings(\n options: TikTokUserFollowingsOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/tiktok/user/followings\", options);\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface WalmartSearchOptions {\n query: string;\n domain?: string;\n device?: string;\n sort_by?: string;\n start_page?: number;\n min_price?: number;\n max_price?: number;\n fulfillment_speed?: string;\n fulfillment_type?: string;\n delivery_zip?: string;\n store_id?: string;\n}\n\nexport interface WalmartProductOptions {\n product_id: string;\n domain?: string;\n device?: string;\n delivery_zip?: string;\n store_id?: string;\n}\n\nexport class WalmartNamespace {\n constructor(private client: Scavio) {}\n\n async search(\n options: WalmartSearchOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/walmart/search\", options);\n }\n\n async product(\n options: WalmartProductOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/walmart/product\", options);\n }\n}\n","import type { Scavio } from \"../client.js\";\n\nexport interface YouTubeSearchOptions {\n query: string;\n upload_date?: string;\n type?: string;\n duration?: string;\n sort_by?: string;\n hd?: boolean;\n subtitles?: boolean;\n creative_commons?: boolean;\n live?: boolean;\n}\n\nexport interface YouTubeMetadataOptions {\n video_id: string;\n}\n\nexport class YouTubeNamespace {\n constructor(private client: Scavio) {}\n\n async search(\n options: YouTubeSearchOptions,\n ): Promise<Record<string, unknown>> {\n const { query, ...rest } = options;\n return this.client._post(\"/api/v1/youtube/search\", {\n search: query,\n ...rest,\n });\n }\n\n async metadata(\n options: YouTubeMetadataOptions,\n ): Promise<Record<string, unknown>> {\n return this.client._post(\"/api/v1/youtube/metadata\", options);\n }\n}\n","import { MissingAPIKeyError, ScavioError } from \"./errors.js\";\nimport { BASE_URL, DEFAULT_TIMEOUT, request } from \"./http.js\";\nimport { RateLimiter } from \"./rate-limiter.js\";\nimport { AmazonNamespace } from \"./namespaces/amazon.js\";\nimport type { GoogleSearchOptions } from \"./namespaces/google.js\";\nimport { GoogleNamespace } from \"./namespaces/google.js\";\nimport { RedditNamespace } from \"./namespaces/reddit.js\";\nimport { TikTokNamespace } from \"./namespaces/tiktok.js\";\nimport { WalmartNamespace } from \"./namespaces/walmart.js\";\nimport { YouTubeNamespace } from \"./namespaces/youtube.js\";\n\nexport interface ScavioConfig {\n apiKey?: string;\n baseUrl?: string;\n timeout?: number;\n maxRequestsPerSecond?: number;\n}\n\nexport class Scavio {\n readonly google: GoogleNamespace;\n readonly amazon: AmazonNamespace;\n readonly walmart: WalmartNamespace;\n readonly youtube: YouTubeNamespace;\n readonly reddit: RedditNamespace;\n readonly tiktok: TikTokNamespace;\n\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly rateLimiter: RateLimiter;\n\n constructor(config?: ScavioConfig) {\n this.apiKey = config?.apiKey ?? process.env.SCAVIO_API_KEY ?? \"\";\n if (!this.apiKey) {\n throw new MissingAPIKeyError();\n }\n\n this.baseUrl = (config?.baseUrl ?? BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = config?.timeout ?? DEFAULT_TIMEOUT;\n\n const rps = config?.maxRequestsPerSecond ?? 1;\n if (rps < 1 || rps > 10) {\n throw new ScavioError(\"maxRequestsPerSecond must be between 1 and 10\");\n }\n this.rateLimiter = new RateLimiter(rps);\n\n this.google = new GoogleNamespace(this);\n this.amazon = new AmazonNamespace(this);\n this.walmart = new WalmartNamespace(this);\n this.youtube = new YouTubeNamespace(this);\n this.reddit = new RedditNamespace(this);\n this.tiktok = new TikTokNamespace(this);\n }\n\n /** @internal */\n async _post(\n path: string,\n body: object,\n ): Promise<Record<string, unknown>> {\n return request({\n method: \"POST\",\n path,\n apiKey: this.apiKey,\n baseUrl: this.baseUrl,\n timeout: this.timeout,\n rateLimiter: this.rateLimiter,\n body: body as Record<string, unknown>,\n });\n }\n\n /** @internal */\n async _get(path: string): Promise<Record<string, unknown>> {\n return request({\n method: \"GET\",\n path,\n apiKey: this.apiKey,\n baseUrl: this.baseUrl,\n timeout: this.timeout,\n rateLimiter: this.rateLimiter,\n });\n }\n\n async search(\n options: GoogleSearchOptions,\n ): Promise<Record<string, unknown>> {\n return this.google.search(options);\n }\n\n async getUsage(): Promise<Record<string, unknown>> {\n return this._get(\"/api/v1/usage\");\n }\n}\n"],"mappings":"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","names":[]}