scrapebadger 0.4.0 → 0.8.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 +28 -291
- package/dist/index.d.cts +3287 -102
- package/dist/index.d.ts +3287 -102
- package/dist/index.js +1524 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1496 -58
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.js +1 -1
- package/dist/twitter/index.js.map +1 -1
- package/dist/twitter/index.mjs +1 -1
- package/dist/twitter/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2192,7 +2192,7 @@ var StreamClient = class {
|
|
|
2192
2192
|
return;
|
|
2193
2193
|
}
|
|
2194
2194
|
if (!reconnect) {
|
|
2195
|
-
const reasonStr = reason instanceof Buffer ? reason.toString() :
|
|
2195
|
+
const reasonStr = reason instanceof Buffer ? reason.toString() : typeof reason === "string" ? reason : "";
|
|
2196
2196
|
emitter.emit(
|
|
2197
2197
|
"error",
|
|
2198
2198
|
new WebSocketStreamError(`WebSocket closed: ${reasonStr || String(code)}`)
|
|
@@ -2433,94 +2433,1523 @@ var WebClient = class {
|
|
|
2433
2433
|
}
|
|
2434
2434
|
/**
|
|
2435
2435
|
* Scrape a web page.
|
|
2436
|
+
*
|
|
2437
|
+
* @param url - The URL to scrape
|
|
2438
|
+
* @param options - Scrape configuration options
|
|
2439
|
+
* @returns The scrape result including content, metadata, and credit usage
|
|
2436
2440
|
*/
|
|
2437
2441
|
async scrape(url, options = {}) {
|
|
2438
2442
|
const body = { url };
|
|
2439
|
-
if (options.
|
|
2440
|
-
if (options.
|
|
2441
|
-
|
|
2442
|
-
if (options.
|
|
2443
|
-
if (options.
|
|
2444
|
-
if (options.
|
|
2445
|
-
if (options.
|
|
2443
|
+
if (options.format !== void 0) body.format = options.format;
|
|
2444
|
+
if (options.renderJs !== void 0) body.render_js = options.renderJs;
|
|
2445
|
+
if (options.engine !== void 0) body.engine = options.engine;
|
|
2446
|
+
if (options.waitFor !== void 0) body.wait_for = options.waitFor;
|
|
2447
|
+
if (options.waitTimeout !== void 0) body.wait_timeout = options.waitTimeout;
|
|
2448
|
+
if (options.waitAfterLoad !== void 0) body.wait_after_load = options.waitAfterLoad;
|
|
2449
|
+
if (options.jsScenario !== void 0) body.js_scenario = options.jsScenario;
|
|
2450
|
+
if (options.sessionId !== void 0) body.session_id = options.sessionId;
|
|
2451
|
+
if (options.retryCount !== void 0) body.retry_count = options.retryCount;
|
|
2452
|
+
if (options.retryOnBlock !== void 0) body.retry_on_block = options.retryOnBlock;
|
|
2453
|
+
if (options.country !== void 0) body.country = options.country;
|
|
2454
|
+
if (options.customHeaders !== void 0) body.custom_headers = options.customHeaders;
|
|
2455
|
+
if (options.screenshot !== void 0) body.screenshot = options.screenshot;
|
|
2456
|
+
if (options.video !== void 0) body.video = options.video;
|
|
2457
|
+
if (options.antiBot !== void 0) body.anti_bot = options.antiBot;
|
|
2458
|
+
if (options.escalate !== void 0) body.escalate = options.escalate;
|
|
2446
2459
|
if (options.maxCost !== void 0) body.max_cost = options.maxCost;
|
|
2447
|
-
if (options.
|
|
2448
|
-
if (options.
|
|
2449
|
-
if (options.
|
|
2450
|
-
if (options.
|
|
2460
|
+
if (options.aiExtract !== void 0) body.ai_extract = options.aiExtract;
|
|
2461
|
+
if (options.aiPrompt !== void 0) body.ai_prompt = options.aiPrompt;
|
|
2462
|
+
if (options.rawContent !== void 0) body.raw_content = options.rawContent;
|
|
2463
|
+
if (options.skipBotDetection !== void 0) body.skip_bot_detection = options.skipBotDetection;
|
|
2451
2464
|
return this.client.request("/v1/web/scrape", {
|
|
2452
2465
|
method: "POST",
|
|
2453
2466
|
body
|
|
2454
2467
|
});
|
|
2455
2468
|
}
|
|
2456
2469
|
/**
|
|
2457
|
-
*
|
|
2470
|
+
* Extract structured data from a web page using AI.
|
|
2471
|
+
*
|
|
2472
|
+
* Convenience wrapper around {@link scrape} that enables AI extraction
|
|
2473
|
+
* with the given prompt and defaults to markdown format.
|
|
2474
|
+
*
|
|
2475
|
+
* @param url - The URL to extract data from
|
|
2476
|
+
* @param prompt - Natural language prompt describing what to extract (max 2000 chars)
|
|
2477
|
+
* @param options - Additional scrape options (aiExtract and aiPrompt are set automatically)
|
|
2478
|
+
* @returns The scrape result with ai_extraction populated
|
|
2458
2479
|
*/
|
|
2459
|
-
async
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
body.viewport_height = options.viewportHeight;
|
|
2466
|
-
if (options.imageFormat && options.imageFormat !== "png")
|
|
2467
|
-
body.image_format = options.imageFormat;
|
|
2468
|
-
if (options.waitFor) body.wait_for = options.waitFor;
|
|
2469
|
-
if (options.timeout !== void 0) body.timeout = options.timeout;
|
|
2470
|
-
return this.client.request("/v1/web/screenshot", {
|
|
2471
|
-
method: "POST",
|
|
2472
|
-
body
|
|
2480
|
+
async extract(url, prompt, options = {}) {
|
|
2481
|
+
return this.scrape(url, {
|
|
2482
|
+
format: "markdown",
|
|
2483
|
+
...options,
|
|
2484
|
+
aiExtract: true,
|
|
2485
|
+
aiPrompt: prompt
|
|
2473
2486
|
});
|
|
2474
2487
|
}
|
|
2475
2488
|
/**
|
|
2476
|
-
*
|
|
2489
|
+
* Detect anti-bot systems on a URL.
|
|
2490
|
+
*
|
|
2491
|
+
* @param url - The URL to analyze
|
|
2492
|
+
* @param options - Detection options
|
|
2493
|
+
* @returns Detection results including identified anti-bot and captcha systems
|
|
2477
2494
|
*/
|
|
2478
|
-
async
|
|
2495
|
+
async detect(url, options = {}) {
|
|
2479
2496
|
const body = { url };
|
|
2480
|
-
if (options.schema) body.extraction_schema = options.schema;
|
|
2481
|
-
if (options.renderJs) body.render_js = true;
|
|
2482
|
-
if (options.waitFor) body.wait_for = options.waitFor;
|
|
2483
2497
|
if (options.timeout !== void 0) body.timeout = options.timeout;
|
|
2484
|
-
|
|
2498
|
+
if (options.country !== void 0) body.country = options.country;
|
|
2499
|
+
return this.client.request("/v1/web/detect", {
|
|
2485
2500
|
method: "POST",
|
|
2486
2501
|
body
|
|
2487
2502
|
});
|
|
2488
2503
|
}
|
|
2504
|
+
};
|
|
2505
|
+
|
|
2506
|
+
// src/vinted/search.ts
|
|
2507
|
+
var SearchClient = class {
|
|
2508
|
+
client;
|
|
2509
|
+
constructor(client) {
|
|
2510
|
+
this.client = client;
|
|
2511
|
+
}
|
|
2489
2512
|
/**
|
|
2490
|
-
*
|
|
2513
|
+
* Search for Vinted items.
|
|
2514
|
+
*
|
|
2515
|
+
* @param params - Search parameters including query, filters, and pagination.
|
|
2516
|
+
* @returns Search results with items and pagination metadata.
|
|
2517
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2518
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
2519
|
+
*
|
|
2520
|
+
* @example
|
|
2521
|
+
* ```typescript
|
|
2522
|
+
* const results = await client.vinted.search.search({
|
|
2523
|
+
* query: "vintage jacket",
|
|
2524
|
+
* market: "fr",
|
|
2525
|
+
* page: 1,
|
|
2526
|
+
* per_page: 20,
|
|
2527
|
+
* order: "newest_first",
|
|
2528
|
+
* });
|
|
2529
|
+
* console.log(`Found ${results.pagination.total_entries} items`);
|
|
2530
|
+
* ```
|
|
2491
2531
|
*/
|
|
2492
|
-
async
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2532
|
+
async search(params) {
|
|
2533
|
+
return this.client.request("/v1/vinted/search", {
|
|
2534
|
+
params: {
|
|
2535
|
+
query: params.query,
|
|
2536
|
+
market: params.market,
|
|
2537
|
+
page: params.page,
|
|
2538
|
+
per_page: params.per_page,
|
|
2539
|
+
price_from: params.price_from,
|
|
2540
|
+
price_to: params.price_to,
|
|
2541
|
+
brand_ids: params.brand_ids,
|
|
2542
|
+
color_ids: params.color_ids,
|
|
2543
|
+
status_ids: params.status_ids,
|
|
2544
|
+
order: params.order
|
|
2545
|
+
}
|
|
2504
2546
|
});
|
|
2505
2547
|
}
|
|
2548
|
+
};
|
|
2549
|
+
|
|
2550
|
+
// src/vinted/items.ts
|
|
2551
|
+
var ItemsClient = class {
|
|
2552
|
+
client;
|
|
2553
|
+
constructor(client) {
|
|
2554
|
+
this.client = client;
|
|
2555
|
+
}
|
|
2506
2556
|
/**
|
|
2507
|
-
*
|
|
2557
|
+
* Get a single item by ID.
|
|
2558
|
+
*
|
|
2559
|
+
* @param itemId - The Vinted item ID to fetch.
|
|
2560
|
+
* @param options - Optional parameters.
|
|
2561
|
+
* @param options.market - Market code (default: "fr").
|
|
2562
|
+
* @returns The item detail response including full item data.
|
|
2563
|
+
* @throws NotFoundError - If the item doesn't exist.
|
|
2564
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2565
|
+
*
|
|
2566
|
+
* @example
|
|
2567
|
+
* ```typescript
|
|
2568
|
+
* const response = await client.vinted.items.get(123456789);
|
|
2569
|
+
* const { item } = response;
|
|
2570
|
+
* console.log(`${item.title}: ${item.description}`);
|
|
2571
|
+
* console.log(`Brand: ${item.brand_title}, Size: ${item.size_title}`);
|
|
2572
|
+
* console.log(`Photos: ${item.photos.length}`);
|
|
2573
|
+
* ```
|
|
2508
2574
|
*/
|
|
2509
|
-
async
|
|
2510
|
-
return this.client.request(
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2575
|
+
async get(itemId, options = {}) {
|
|
2576
|
+
return this.client.request(
|
|
2577
|
+
`/v1/vinted/items/${itemId}`,
|
|
2578
|
+
{ params: { market: options.market } }
|
|
2579
|
+
);
|
|
2580
|
+
}
|
|
2581
|
+
};
|
|
2582
|
+
|
|
2583
|
+
// src/vinted/users.ts
|
|
2584
|
+
var UsersClient2 = class {
|
|
2585
|
+
client;
|
|
2586
|
+
constructor(client) {
|
|
2587
|
+
this.client = client;
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Get a user's profile.
|
|
2591
|
+
*
|
|
2592
|
+
* @param userId - The Vinted user ID.
|
|
2593
|
+
* @param options - Optional parameters.
|
|
2594
|
+
* @param options.market - Market code (default: "fr").
|
|
2595
|
+
* @returns The user profile response.
|
|
2596
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
2597
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2598
|
+
*
|
|
2599
|
+
* @example
|
|
2600
|
+
* ```typescript
|
|
2601
|
+
* const response = await client.vinted.users.getProfile(12345);
|
|
2602
|
+
* const { user } = response;
|
|
2603
|
+
* console.log(`${user.login} from ${user.city}, ${user.country_code}`);
|
|
2604
|
+
* console.log(`Reputation: ${user.feedback_reputation}`);
|
|
2605
|
+
* console.log(`Items: ${user.item_count}, Followers: ${user.followers_count}`);
|
|
2606
|
+
* ```
|
|
2607
|
+
*/
|
|
2608
|
+
async getProfile(userId, options = {}) {
|
|
2609
|
+
return this.client.request(
|
|
2610
|
+
`/v1/vinted/users/${userId}`,
|
|
2611
|
+
{ params: { market: options.market } }
|
|
2612
|
+
);
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Get items listed by a user.
|
|
2616
|
+
*
|
|
2617
|
+
* @param userId - The Vinted user ID.
|
|
2618
|
+
* @param options - Optional parameters for pagination and market.
|
|
2619
|
+
* @param options.market - Market code (default: "fr").
|
|
2620
|
+
* @param options.page - Page number.
|
|
2621
|
+
* @param options.per_page - Items per page.
|
|
2622
|
+
* @returns The user's items with pagination metadata.
|
|
2623
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
2624
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2625
|
+
*
|
|
2626
|
+
* @example
|
|
2627
|
+
* ```typescript
|
|
2628
|
+
* const response = await client.vinted.users.getItems(12345, {
|
|
2629
|
+
* market: "de",
|
|
2630
|
+
* page: 1,
|
|
2631
|
+
* per_page: 20,
|
|
2632
|
+
* });
|
|
2633
|
+
* console.log(`Page ${response.pagination.current_page} of ${response.pagination.total_pages}`);
|
|
2634
|
+
* for (const item of response.items) {
|
|
2635
|
+
* console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);
|
|
2636
|
+
* }
|
|
2637
|
+
* ```
|
|
2638
|
+
*/
|
|
2639
|
+
async getItems(userId, options = {}) {
|
|
2640
|
+
return this.client.request(
|
|
2641
|
+
`/v1/vinted/users/${userId}/items`,
|
|
2642
|
+
{
|
|
2643
|
+
params: {
|
|
2644
|
+
market: options.market,
|
|
2645
|
+
page: options.page,
|
|
2646
|
+
per_page: options.per_page
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
);
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
|
|
2653
|
+
// src/vinted/reference.ts
|
|
2654
|
+
var ReferenceClient = class {
|
|
2655
|
+
client;
|
|
2656
|
+
constructor(client) {
|
|
2657
|
+
this.client = client;
|
|
2658
|
+
}
|
|
2659
|
+
/**
|
|
2660
|
+
* Search for brands by keyword.
|
|
2661
|
+
*
|
|
2662
|
+
* @param options - Optional parameters.
|
|
2663
|
+
* @param options.keyword - Brand name to search for.
|
|
2664
|
+
* @param options.market - Market code (default: "fr").
|
|
2665
|
+
* @param options.per_page - Number of results per page.
|
|
2666
|
+
* @returns Brands matching the keyword.
|
|
2667
|
+
*
|
|
2668
|
+
* @example
|
|
2669
|
+
* ```typescript
|
|
2670
|
+
* const response = await client.vinted.reference.brands({
|
|
2671
|
+
* keyword: "adidas",
|
|
2672
|
+
* market: "de",
|
|
2673
|
+
* per_page: 10,
|
|
2674
|
+
* });
|
|
2675
|
+
* for (const brand of response.brands) {
|
|
2676
|
+
* console.log(`${brand.title} (${brand.slug}): ${brand.item_count} items`);
|
|
2677
|
+
* }
|
|
2678
|
+
* ```
|
|
2679
|
+
*/
|
|
2680
|
+
async brands(options = {}) {
|
|
2681
|
+
return this.client.request("/v1/vinted/brands", {
|
|
2682
|
+
params: {
|
|
2683
|
+
keyword: options.keyword,
|
|
2684
|
+
market: options.market,
|
|
2685
|
+
per_page: options.per_page
|
|
2516
2686
|
}
|
|
2517
2687
|
});
|
|
2518
2688
|
}
|
|
2519
2689
|
/**
|
|
2520
|
-
*
|
|
2690
|
+
* Get available colors for a market.
|
|
2691
|
+
*
|
|
2692
|
+
* @param options - Optional parameters.
|
|
2693
|
+
* @param options.market - Market code (default: "fr").
|
|
2694
|
+
* @returns List of available colors.
|
|
2695
|
+
*
|
|
2696
|
+
* @example
|
|
2697
|
+
* ```typescript
|
|
2698
|
+
* const response = await client.vinted.reference.colors({ market: "fr" });
|
|
2699
|
+
* for (const color of response.colors) {
|
|
2700
|
+
* console.log(`${color.title} (#${color.hex})`);
|
|
2701
|
+
* }
|
|
2702
|
+
* ```
|
|
2703
|
+
*/
|
|
2704
|
+
async colors(options = {}) {
|
|
2705
|
+
return this.client.request("/v1/vinted/colors", {
|
|
2706
|
+
params: { market: options.market }
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Get available item condition statuses for a market.
|
|
2711
|
+
*
|
|
2712
|
+
* @param options - Optional parameters.
|
|
2713
|
+
* @param options.market - Market code (default: "fr").
|
|
2714
|
+
* @returns List of item condition statuses.
|
|
2715
|
+
*
|
|
2716
|
+
* @example
|
|
2717
|
+
* ```typescript
|
|
2718
|
+
* const response = await client.vinted.reference.statuses({ market: "fr" });
|
|
2719
|
+
* for (const status of response.statuses) {
|
|
2720
|
+
* console.log(`${status.id}: ${status.title}`);
|
|
2721
|
+
* }
|
|
2722
|
+
* ```
|
|
2723
|
+
*/
|
|
2724
|
+
async statuses(options = {}) {
|
|
2725
|
+
return this.client.request("/v1/vinted/statuses", {
|
|
2726
|
+
params: { market: options.market }
|
|
2727
|
+
});
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* Get all available Vinted markets.
|
|
2731
|
+
*
|
|
2732
|
+
* @returns List of all supported Vinted markets/countries.
|
|
2733
|
+
*
|
|
2734
|
+
* @example
|
|
2735
|
+
* ```typescript
|
|
2736
|
+
* const response = await client.vinted.reference.markets();
|
|
2737
|
+
* for (const market of response.markets) {
|
|
2738
|
+
* console.log(`${market.name}: ${market.domain} (${market.currency})`);
|
|
2739
|
+
* }
|
|
2740
|
+
* ```
|
|
2741
|
+
*/
|
|
2742
|
+
async markets() {
|
|
2743
|
+
return this.client.request("/v1/vinted/markets");
|
|
2744
|
+
}
|
|
2745
|
+
};
|
|
2746
|
+
|
|
2747
|
+
// src/vinted/client.ts
|
|
2748
|
+
var VintedClient = class {
|
|
2749
|
+
/** Client for item search operations */
|
|
2750
|
+
search;
|
|
2751
|
+
/** Client for individual item operations */
|
|
2752
|
+
items;
|
|
2753
|
+
/** Client for user operations */
|
|
2754
|
+
users;
|
|
2755
|
+
/** Client for reference data (brands, colors, statuses, markets) */
|
|
2756
|
+
reference;
|
|
2757
|
+
/**
|
|
2758
|
+
* Create a new Vinted client.
|
|
2759
|
+
*
|
|
2760
|
+
* @param client - The base HTTP client for making requests.
|
|
2761
|
+
*/
|
|
2762
|
+
constructor(client) {
|
|
2763
|
+
this.search = new SearchClient(client);
|
|
2764
|
+
this.items = new ItemsClient(client);
|
|
2765
|
+
this.users = new UsersClient2(client);
|
|
2766
|
+
this.reference = new ReferenceClient(client);
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
|
|
2770
|
+
// src/google/ai-mode.ts
|
|
2771
|
+
var AiModeClient = class {
|
|
2772
|
+
constructor(client) {
|
|
2773
|
+
this.client = client;
|
|
2774
|
+
}
|
|
2775
|
+
async search(params) {
|
|
2776
|
+
return this.client.request("/v1/google/ai-mode/search", {
|
|
2777
|
+
params: { ...params }
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
};
|
|
2781
|
+
|
|
2782
|
+
// src/google/autocomplete.ts
|
|
2783
|
+
var AutocompleteClient = class {
|
|
2784
|
+
constructor(client) {
|
|
2785
|
+
this.client = client;
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Get Google autocomplete suggestions for a query.
|
|
2789
|
+
*
|
|
2790
|
+
* @example
|
|
2791
|
+
* ```typescript
|
|
2792
|
+
* const res = await client.google.autocomplete.get({ q: "apple" });
|
|
2793
|
+
* for (const s of res.suggestions) {
|
|
2794
|
+
* console.log(s.value, s.entity_name, s.thumbnail);
|
|
2795
|
+
* }
|
|
2796
|
+
* ```
|
|
2797
|
+
*/
|
|
2798
|
+
async get(params) {
|
|
2799
|
+
return this.client.request("/v1/google/autocomplete", {
|
|
2800
|
+
params: { ...params }
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2803
|
+
};
|
|
2804
|
+
|
|
2805
|
+
// src/google/finance.ts
|
|
2806
|
+
var FinanceClient = class {
|
|
2807
|
+
constructor(client) {
|
|
2808
|
+
this.client = client;
|
|
2809
|
+
}
|
|
2810
|
+
async quote(params) {
|
|
2811
|
+
return this.client.request("/v1/google/finance/quote", {
|
|
2812
|
+
params: { ...params }
|
|
2813
|
+
});
|
|
2814
|
+
}
|
|
2815
|
+
};
|
|
2816
|
+
|
|
2817
|
+
// src/google/flights.ts
|
|
2818
|
+
var FlightsClient = class {
|
|
2819
|
+
constructor(client) {
|
|
2820
|
+
this.client = client;
|
|
2821
|
+
}
|
|
2822
|
+
/** Search Google Flights for available itineraries. */
|
|
2823
|
+
async search(params) {
|
|
2824
|
+
return this.client.request("/v1/google/flights/search", {
|
|
2825
|
+
params: { ...params }
|
|
2826
|
+
});
|
|
2827
|
+
}
|
|
2828
|
+
};
|
|
2829
|
+
|
|
2830
|
+
// src/google/hotels.ts
|
|
2831
|
+
var HotelsClient = class {
|
|
2832
|
+
constructor(client) {
|
|
2833
|
+
this.client = client;
|
|
2834
|
+
}
|
|
2835
|
+
async search(params) {
|
|
2836
|
+
return this.client.request("/v1/google/hotels/search", {
|
|
2837
|
+
params: { ...params }
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
async details(params) {
|
|
2841
|
+
return this.client.request("/v1/google/hotels/details", {
|
|
2842
|
+
params: { ...params }
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2845
|
+
};
|
|
2846
|
+
|
|
2847
|
+
// src/google/images.ts
|
|
2848
|
+
var ImagesClient = class {
|
|
2849
|
+
constructor(client) {
|
|
2850
|
+
this.client = client;
|
|
2851
|
+
}
|
|
2852
|
+
async search(params) {
|
|
2853
|
+
return this.client.request("/v1/google/images/search", {
|
|
2854
|
+
params: { ...params }
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
};
|
|
2858
|
+
|
|
2859
|
+
// src/google/jobs.ts
|
|
2860
|
+
var JobsClient = class {
|
|
2861
|
+
constructor(client) {
|
|
2862
|
+
this.client = client;
|
|
2863
|
+
}
|
|
2864
|
+
async search(params) {
|
|
2865
|
+
return this.client.request("/v1/google/jobs/search", {
|
|
2866
|
+
params: { ...params }
|
|
2867
|
+
});
|
|
2868
|
+
}
|
|
2869
|
+
};
|
|
2870
|
+
|
|
2871
|
+
// src/google/lens.ts
|
|
2872
|
+
var LensClient = class {
|
|
2873
|
+
constructor(client) {
|
|
2874
|
+
this.client = client;
|
|
2875
|
+
}
|
|
2876
|
+
async search(params) {
|
|
2877
|
+
return this.client.request("/v1/google/lens/search", {
|
|
2878
|
+
params: { ...params }
|
|
2879
|
+
});
|
|
2880
|
+
}
|
|
2881
|
+
};
|
|
2882
|
+
|
|
2883
|
+
// src/google/maps.ts
|
|
2884
|
+
var MapsClient = class {
|
|
2885
|
+
constructor(client) {
|
|
2886
|
+
this.client = client;
|
|
2887
|
+
}
|
|
2888
|
+
/**
|
|
2889
|
+
* Search Maps for places by text query, place_id, or ludocid.
|
|
2890
|
+
*
|
|
2891
|
+
* Returns up to 20 results per page with full details (place_id,
|
|
2892
|
+
* data_id, GPS, rating, reviews, address, phone, website, extensions,
|
|
2893
|
+
* weekly hours, thumbnail) in a single call.
|
|
2894
|
+
*/
|
|
2895
|
+
async search(params) {
|
|
2896
|
+
if (!params.q && !params.place_id && !params.ludocid) {
|
|
2897
|
+
throw new Error("q, place_id, or ludocid is required");
|
|
2898
|
+
}
|
|
2899
|
+
return this.client.request("/v1/google/maps/search", {
|
|
2900
|
+
params: { ...params }
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
/**
|
|
2904
|
+
* Get full place detail by `place_id` or `data_id`.
|
|
2905
|
+
*
|
|
2906
|
+
* Returns title, address, phone, website, GPS, rating, reviews_count,
|
|
2907
|
+
* rating_summary (per-star distribution), categories, extensions
|
|
2908
|
+
* (service_options, accessibility, offerings, payments), weekly
|
|
2909
|
+
* operating hours, popular_times graph, provider_id,
|
|
2910
|
+
* permanently_closed, thumbnail, and photo list.
|
|
2911
|
+
*/
|
|
2912
|
+
async place(params) {
|
|
2913
|
+
if (!params.place_id && !params.data_id) {
|
|
2914
|
+
throw new Error("place_id or data_id is required");
|
|
2915
|
+
}
|
|
2916
|
+
return this.client.request("/v1/google/maps/place", {
|
|
2917
|
+
params: { ...params }
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Get reviews for a place (paginated, optional topic filter).
|
|
2922
|
+
*
|
|
2923
|
+
* Pass the `next_page_token` from `response.pagination.next` for
|
|
2924
|
+
* subsequent pages, or use `topic_id` from `response.topics[].id`
|
|
2925
|
+
* to scope to a specific review topic.
|
|
2926
|
+
*/
|
|
2927
|
+
async reviews(params) {
|
|
2928
|
+
return this.client.request("/v1/google/maps/reviews", {
|
|
2929
|
+
params: { ...params }
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
/**
|
|
2933
|
+
* Get photos for a place with place-specific categories.
|
|
2934
|
+
*
|
|
2935
|
+
* Returns place-specific categories (Menu, Vibe, Comfort food, dish
|
|
2936
|
+
* names) and photo URLs from all CDN families. Use `category_id` to
|
|
2937
|
+
* scope to a category, or `page_size: 200` to fetch all photos in
|
|
2938
|
+
* one call (Google caps at ~120 photos per response).
|
|
2939
|
+
*/
|
|
2940
|
+
async photos(params) {
|
|
2941
|
+
return this.client.request("/v1/google/maps/photos", {
|
|
2942
|
+
params: { ...params }
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
/** Get business posts (promotional updates, announcements) for a place. */
|
|
2946
|
+
async posts(params) {
|
|
2947
|
+
if (!params.data_id && !params.place_id) {
|
|
2948
|
+
throw new Error("data_id or place_id is required");
|
|
2949
|
+
}
|
|
2950
|
+
return this.client.request("/v1/google/maps/posts", {
|
|
2951
|
+
params: { ...params }
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
|
|
2956
|
+
// src/google/news.ts
|
|
2957
|
+
var NewsClient = class {
|
|
2958
|
+
constructor(client) {
|
|
2959
|
+
this.client = client;
|
|
2960
|
+
}
|
|
2961
|
+
/**
|
|
2962
|
+
* Search Google News. One of `q`, `topic_token`, `publication_token`,
|
|
2963
|
+
* or `story_token` is required (or pass no params for the trending
|
|
2964
|
+
* home feed). Returns `menu_links`, `news_results`, `related_topics`.
|
|
2965
|
+
*/
|
|
2966
|
+
async search(params = {}) {
|
|
2967
|
+
if (!params.q && !params.topic_token && !params.publication_token && !params.story_token) {
|
|
2968
|
+
throw new Error("Provide q, topic_token, publication_token, or story_token");
|
|
2969
|
+
}
|
|
2970
|
+
return this.client.request("/v1/google/news/search", {
|
|
2971
|
+
params: { ...params }
|
|
2972
|
+
});
|
|
2973
|
+
}
|
|
2974
|
+
async topics(params) {
|
|
2975
|
+
return this.client.request("/v1/google/news/topics", {
|
|
2976
|
+
params: { ...params }
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
async trending(params = {}) {
|
|
2980
|
+
return this.client.request("/v1/google/news/trending", {
|
|
2981
|
+
params: { ...params }
|
|
2982
|
+
});
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
|
|
2986
|
+
// src/google/patents.ts
|
|
2987
|
+
var PatentsClient = class {
|
|
2988
|
+
constructor(client) {
|
|
2989
|
+
this.client = client;
|
|
2990
|
+
}
|
|
2991
|
+
async search(params) {
|
|
2992
|
+
return this.client.request("/v1/google/patents/search", {
|
|
2993
|
+
params: { ...params }
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2996
|
+
/**
|
|
2997
|
+
* Get rich patent document details by patent number.
|
|
2998
|
+
*
|
|
2999
|
+
* Response includes full abstract + every claim + complete description,
|
|
3000
|
+
* plus structured `cpc_classifications` (code + description), split
|
|
3001
|
+
* `backward_citations` / `forward_citations` (with `primary_examiner`
|
|
3002
|
+
* flag), `non_patent_citations`, `concepts` (research fields),
|
|
3003
|
+
* `legal_events` (prosecution history), `figures` (full-res URLs),
|
|
3004
|
+
* every `inventor`, and the full `assignees_original` history.
|
|
2521
3005
|
*/
|
|
2522
|
-
async
|
|
2523
|
-
return this.
|
|
3006
|
+
async detail(params) {
|
|
3007
|
+
return this.client.request("/v1/google/patents/detail", {
|
|
3008
|
+
params: { ...params }
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
};
|
|
3012
|
+
|
|
3013
|
+
// src/google/products.ts
|
|
3014
|
+
var ProductsClient = class {
|
|
3015
|
+
constructor(client) {
|
|
3016
|
+
this.client = client;
|
|
3017
|
+
}
|
|
3018
|
+
async detail(params) {
|
|
3019
|
+
return this.client.request("/v1/google/products/detail", {
|
|
3020
|
+
params: { ...params }
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
};
|
|
3024
|
+
|
|
3025
|
+
// src/google/scholar.ts
|
|
3026
|
+
var ScholarClient = class {
|
|
3027
|
+
constructor(client) {
|
|
3028
|
+
this.client = client;
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* Search Google Scholar. Returns each result with doc `id`, `type`
|
|
3032
|
+
* badge, wrapped `inline_links`, PDF `resources`, and structured
|
|
3033
|
+
* authors. Envelope includes `scholar_results` alias,
|
|
3034
|
+
* `related_searches`, and matched `profiles` cards.
|
|
3035
|
+
*/
|
|
3036
|
+
async search(params) {
|
|
3037
|
+
return this.client.request("/v1/google/scholar/search", {
|
|
3038
|
+
params: { ...params }
|
|
3039
|
+
});
|
|
3040
|
+
}
|
|
3041
|
+
/** Search Google Scholar for author profiles by name. */
|
|
3042
|
+
async profiles(params) {
|
|
3043
|
+
return this.client.request("/v1/google/scholar/profiles", {
|
|
3044
|
+
params: { ...params }
|
|
3045
|
+
});
|
|
3046
|
+
}
|
|
3047
|
+
/**
|
|
3048
|
+
* Full Scholar author profile: structured `interests_detailed`,
|
|
3049
|
+
* publications (with per-article `citation_id` + nested
|
|
3050
|
+
* `cited_by{value, link, citation_id}`), stats, and co-authors.
|
|
3051
|
+
*/
|
|
3052
|
+
async author(params) {
|
|
3053
|
+
return this.client.request("/v1/google/scholar/author", {
|
|
3054
|
+
params: { ...params }
|
|
3055
|
+
});
|
|
3056
|
+
}
|
|
3057
|
+
/** Citations-per-year chart for a Scholar author. */
|
|
3058
|
+
async authorCitation(params) {
|
|
3059
|
+
return this.client.request("/v1/google/scholar/author/citation", {
|
|
3060
|
+
params: { ...params }
|
|
3061
|
+
});
|
|
3062
|
+
}
|
|
3063
|
+
/**
|
|
3064
|
+
* MLA / APA / Chicago / Harvard / Vancouver citation formats plus
|
|
3065
|
+
* BibTeX / RIS / EndNote / RefWorks export links for a paper.
|
|
3066
|
+
*/
|
|
3067
|
+
async cite(params) {
|
|
3068
|
+
return this.client.request("/v1/google/scholar/cite", {
|
|
3069
|
+
params: { ...params }
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
};
|
|
3073
|
+
|
|
3074
|
+
// src/google/search.ts
|
|
3075
|
+
var SearchClient2 = class {
|
|
3076
|
+
constructor(client) {
|
|
3077
|
+
this.client = client;
|
|
3078
|
+
}
|
|
3079
|
+
/**
|
|
3080
|
+
* Search Google and get a structured SERP response with organic results,
|
|
3081
|
+
* knowledge graph, People Also Ask, related searches, AI overview, and
|
|
3082
|
+
* pagination.
|
|
3083
|
+
*/
|
|
3084
|
+
async search(params) {
|
|
3085
|
+
return this.client.request("/v1/google/search", { params: { ...params } });
|
|
3086
|
+
}
|
|
3087
|
+
/**
|
|
3088
|
+
* Lightweight Google Search — organic results + related searches only.
|
|
3089
|
+
*
|
|
3090
|
+
* ~40% faster than {@link search}. Skips ads, Knowledge Graph, AI
|
|
3091
|
+
* Overview, local pack, news, inline videos, and shopping blocks.
|
|
3092
|
+
* Credit cost is configured per-endpoint by admins — query
|
|
3093
|
+
* `/public/pricing` for the live rate.
|
|
3094
|
+
*
|
|
3095
|
+
* @example
|
|
3096
|
+
* ```typescript
|
|
3097
|
+
* const lite = await client.google.search.light({ q: "python 3.13" });
|
|
3098
|
+
* ```
|
|
3099
|
+
*/
|
|
3100
|
+
async light(params) {
|
|
3101
|
+
return this.client.request("/v1/google/search", {
|
|
3102
|
+
params: { ...params, mode: "fast" }
|
|
3103
|
+
});
|
|
3104
|
+
}
|
|
3105
|
+
};
|
|
3106
|
+
|
|
3107
|
+
// src/google/shopping.ts
|
|
3108
|
+
var ShoppingClient = class {
|
|
3109
|
+
constructor(client) {
|
|
3110
|
+
this.client = client;
|
|
3111
|
+
}
|
|
3112
|
+
/** Search Google Shopping for products. */
|
|
3113
|
+
async search(params) {
|
|
3114
|
+
return this.client.request("/v1/google/shopping/search", {
|
|
3115
|
+
params: { ...params }
|
|
3116
|
+
});
|
|
3117
|
+
}
|
|
3118
|
+
/** Fetch the Google Shopping product detail page by `product_id`. */
|
|
3119
|
+
async product(params) {
|
|
3120
|
+
return this.client.request("/v1/google/shopping/product", {
|
|
3121
|
+
params: { ...params }
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
/**
|
|
3125
|
+
* Resolve the direct merchant URL for a Shopping product tile via
|
|
3126
|
+
* Google's "I'm Feeling Lucky" redirect (scoped to the card's `source`
|
|
3127
|
+
* merchant via the `site:` operator). You only pay for the call when
|
|
3128
|
+
* you actually want the merchant link — no bulk enrichment of every
|
|
3129
|
+
* tile.
|
|
3130
|
+
*/
|
|
3131
|
+
async click(params) {
|
|
3132
|
+
return this.client.request("/v1/google/shopping/product/click", {
|
|
3133
|
+
params: { ...params }
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3136
|
+
};
|
|
3137
|
+
|
|
3138
|
+
// src/google/shorts.ts
|
|
3139
|
+
var ShortsClient = class {
|
|
3140
|
+
constructor(client) {
|
|
3141
|
+
this.client = client;
|
|
3142
|
+
}
|
|
3143
|
+
async search(params) {
|
|
3144
|
+
return this.client.request("/v1/google/shorts/search", {
|
|
3145
|
+
params: { ...params }
|
|
3146
|
+
});
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3149
|
+
|
|
3150
|
+
// src/google/trends.ts
|
|
3151
|
+
var TrendsClient2 = class {
|
|
3152
|
+
constructor(client) {
|
|
3153
|
+
this.client = client;
|
|
3154
|
+
}
|
|
3155
|
+
async interest(params) {
|
|
3156
|
+
return this.client.request("/v1/google/trends/interest", {
|
|
3157
|
+
params: { ...params }
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
async regions(params) {
|
|
3161
|
+
return this.client.request("/v1/google/trends/regions", {
|
|
3162
|
+
params: { ...params }
|
|
3163
|
+
});
|
|
3164
|
+
}
|
|
3165
|
+
async related(params) {
|
|
3166
|
+
return this.client.request("/v1/google/trends/related", {
|
|
3167
|
+
params: { ...params }
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3170
|
+
async trending(params = {}) {
|
|
3171
|
+
return this.client.request("/v1/google/trends/trending", {
|
|
3172
|
+
params: { ...params }
|
|
3173
|
+
});
|
|
3174
|
+
}
|
|
3175
|
+
/**
|
|
3176
|
+
* Current trending searches with the full Google Trends UI filter set
|
|
3177
|
+
* — `geo`, `hours`, `category`, `status`, `sort`, `hl`.
|
|
3178
|
+
*/
|
|
3179
|
+
async trendingNow(params = {}) {
|
|
3180
|
+
return this.client.request("/v1/google/trends/trending-now", {
|
|
3181
|
+
params: { ...params }
|
|
3182
|
+
});
|
|
3183
|
+
}
|
|
3184
|
+
/**
|
|
3185
|
+
* Unified Google Trends query — pick the response shape via
|
|
3186
|
+
* `data_type` (TIMESERIES | GEO_MAP | GEO_MAP_0 | RELATED_TOPICS |
|
|
3187
|
+
* RELATED_QUERIES).
|
|
3188
|
+
*/
|
|
3189
|
+
async search(params) {
|
|
3190
|
+
return this.client.request("/v1/google/trends/search", {
|
|
3191
|
+
params: { ...params }
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* Return categorized Knowledge Graph topic entities (`mid`, `type`,
|
|
3196
|
+
* direct link into Trends explore) for a query prefix. Distinct from
|
|
3197
|
+
* Google Search autocomplete.
|
|
3198
|
+
*/
|
|
3199
|
+
async autocomplete(params) {
|
|
3200
|
+
return this.client.request("/v1/google/trends/autocomplete", {
|
|
3201
|
+
params: { ...params }
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
};
|
|
3205
|
+
|
|
3206
|
+
// src/google/videos.ts
|
|
3207
|
+
var VideosClient = class {
|
|
3208
|
+
constructor(client) {
|
|
3209
|
+
this.client = client;
|
|
3210
|
+
}
|
|
3211
|
+
async search(params) {
|
|
3212
|
+
return this.client.request("/v1/google/videos/search", {
|
|
3213
|
+
params: { ...params }
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
};
|
|
3217
|
+
|
|
3218
|
+
// src/google/client.ts
|
|
3219
|
+
var GoogleClient = class {
|
|
3220
|
+
/** Google Web Search (SERP) — with optional deferred AI Overview follow-up. */
|
|
3221
|
+
search;
|
|
3222
|
+
/** Google Maps — places, reviews, photos, posts. */
|
|
3223
|
+
maps;
|
|
3224
|
+
/** Google News — articles, topics, trending. */
|
|
3225
|
+
news;
|
|
3226
|
+
/** Google Hotels — search and property details. */
|
|
3227
|
+
hotels;
|
|
3228
|
+
/** Google Trends — interest, regions, related, trending, topic autocomplete. */
|
|
3229
|
+
trends;
|
|
3230
|
+
/** Google Jobs. */
|
|
3231
|
+
jobs;
|
|
3232
|
+
/** Google Shopping — search, details, click enrichment. */
|
|
3233
|
+
shopping;
|
|
3234
|
+
/** Google Patents — search and document details. */
|
|
3235
|
+
patents;
|
|
3236
|
+
/** Google Scholar — search, profiles, author, author citation, cite formats. */
|
|
3237
|
+
scholar;
|
|
3238
|
+
/** Google Autocomplete — search suggestions. */
|
|
3239
|
+
autocomplete;
|
|
3240
|
+
/** Google Images. */
|
|
3241
|
+
images;
|
|
3242
|
+
/** Google Videos. */
|
|
3243
|
+
videos;
|
|
3244
|
+
/** Google Finance — stock and index quotes. */
|
|
3245
|
+
finance;
|
|
3246
|
+
/** Google AI Mode — generative answer responses. */
|
|
3247
|
+
aiMode;
|
|
3248
|
+
/** Google Lens — visual image search. */
|
|
3249
|
+
lens;
|
|
3250
|
+
/** Google Shorts — short-form vertical video results (udm=39). */
|
|
3251
|
+
shorts;
|
|
3252
|
+
/** Google Flights — one-way, round-trip, and multi-city itineraries. */
|
|
3253
|
+
flights;
|
|
3254
|
+
/** Google Products — immersive product detail. */
|
|
3255
|
+
products;
|
|
3256
|
+
constructor(client) {
|
|
3257
|
+
this.search = new SearchClient2(client);
|
|
3258
|
+
this.maps = new MapsClient(client);
|
|
3259
|
+
this.news = new NewsClient(client);
|
|
3260
|
+
this.hotels = new HotelsClient(client);
|
|
3261
|
+
this.trends = new TrendsClient2(client);
|
|
3262
|
+
this.jobs = new JobsClient(client);
|
|
3263
|
+
this.shopping = new ShoppingClient(client);
|
|
3264
|
+
this.patents = new PatentsClient(client);
|
|
3265
|
+
this.scholar = new ScholarClient(client);
|
|
3266
|
+
this.autocomplete = new AutocompleteClient(client);
|
|
3267
|
+
this.images = new ImagesClient(client);
|
|
3268
|
+
this.videos = new VideosClient(client);
|
|
3269
|
+
this.finance = new FinanceClient(client);
|
|
3270
|
+
this.aiMode = new AiModeClient(client);
|
|
3271
|
+
this.lens = new LensClient(client);
|
|
3272
|
+
this.shorts = new ShortsClient(client);
|
|
3273
|
+
this.flights = new FlightsClient(client);
|
|
3274
|
+
this.products = new ProductsClient(client);
|
|
3275
|
+
}
|
|
3276
|
+
};
|
|
3277
|
+
|
|
3278
|
+
// src/reddit/search.ts
|
|
3279
|
+
var SearchClient3 = class {
|
|
3280
|
+
client;
|
|
3281
|
+
constructor(client) {
|
|
3282
|
+
this.client = client;
|
|
3283
|
+
}
|
|
3284
|
+
/**
|
|
3285
|
+
* Search Reddit posts.
|
|
3286
|
+
*
|
|
3287
|
+
* @param options - Search parameters.
|
|
3288
|
+
* @param options.query - Search query string.
|
|
3289
|
+
* @param options.subreddit - Restrict search to a specific subreddit.
|
|
3290
|
+
* @param options.sort - Sort order (relevance, hot, top, new, comments).
|
|
3291
|
+
* @param options.time - Time filter (hour, day, week, month, year, all).
|
|
3292
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3293
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3294
|
+
* @returns Search results with posts and pagination metadata.
|
|
3295
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3296
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
3297
|
+
*
|
|
3298
|
+
* @example
|
|
3299
|
+
* ```typescript
|
|
3300
|
+
* const results = await client.reddit.search.posts({
|
|
3301
|
+
* query: "best practices",
|
|
3302
|
+
* subreddit: "programming",
|
|
3303
|
+
* sort: "top",
|
|
3304
|
+
* time: "month",
|
|
3305
|
+
* limit: 25,
|
|
3306
|
+
* });
|
|
3307
|
+
* console.log(`Found ${results.posts.length} posts`);
|
|
3308
|
+
* ```
|
|
3309
|
+
*/
|
|
3310
|
+
async posts(options) {
|
|
3311
|
+
return this.client.request("/v1/reddit/search/posts", {
|
|
3312
|
+
params: {
|
|
3313
|
+
query: options.query,
|
|
3314
|
+
subreddit: options.subreddit,
|
|
3315
|
+
sort: options.sort,
|
|
3316
|
+
time: options.time,
|
|
3317
|
+
after: options.after,
|
|
3318
|
+
limit: options.limit
|
|
3319
|
+
}
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
/**
|
|
3323
|
+
* Search Reddit subreddits.
|
|
3324
|
+
*
|
|
3325
|
+
* @param options - Search parameters.
|
|
3326
|
+
* @param options.query - Search query string.
|
|
3327
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3328
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3329
|
+
* @returns Matching subreddits with pagination metadata.
|
|
3330
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3331
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
3332
|
+
*
|
|
3333
|
+
* @example
|
|
3334
|
+
* ```typescript
|
|
3335
|
+
* const results = await client.reddit.search.subreddits({
|
|
3336
|
+
* query: "javascript",
|
|
3337
|
+
* limit: 10,
|
|
3338
|
+
* });
|
|
3339
|
+
* for (const sub of results.subreddits) {
|
|
3340
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
3341
|
+
* }
|
|
3342
|
+
* ```
|
|
3343
|
+
*/
|
|
3344
|
+
async subreddits(options) {
|
|
3345
|
+
return this.client.request(
|
|
3346
|
+
"/v1/reddit/search/subreddits",
|
|
3347
|
+
{
|
|
3348
|
+
params: {
|
|
3349
|
+
query: options.query,
|
|
3350
|
+
after: options.after,
|
|
3351
|
+
limit: options.limit
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
);
|
|
3355
|
+
}
|
|
3356
|
+
/**
|
|
3357
|
+
* Search Reddit users.
|
|
3358
|
+
*
|
|
3359
|
+
* @param options - Search parameters.
|
|
3360
|
+
* @param options.query - Search query string.
|
|
3361
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3362
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3363
|
+
* @returns Matching users with pagination metadata.
|
|
3364
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3365
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
3366
|
+
*
|
|
3367
|
+
* @example
|
|
3368
|
+
* ```typescript
|
|
3369
|
+
* const results = await client.reddit.search.users({
|
|
3370
|
+
* query: "john",
|
|
3371
|
+
* limit: 20,
|
|
3372
|
+
* });
|
|
3373
|
+
* for (const user of results.users) {
|
|
3374
|
+
* console.log(`u/${user.name}: ${user.total_karma.toLocaleString()} karma`);
|
|
3375
|
+
* }
|
|
3376
|
+
* ```
|
|
3377
|
+
*/
|
|
3378
|
+
async users(options) {
|
|
3379
|
+
return this.client.request(
|
|
3380
|
+
"/v1/reddit/search/users",
|
|
3381
|
+
{
|
|
3382
|
+
params: {
|
|
3383
|
+
query: options.query,
|
|
3384
|
+
after: options.after,
|
|
3385
|
+
limit: options.limit
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
);
|
|
3389
|
+
}
|
|
3390
|
+
/**
|
|
3391
|
+
* Get Reddit posts linking to a specific domain.
|
|
3392
|
+
*
|
|
3393
|
+
* @param options - Request parameters.
|
|
3394
|
+
* @param options.domain - Domain name to search for (e.g. "github.com").
|
|
3395
|
+
* @param options.sort - Sort order (hot, new, top, rising).
|
|
3396
|
+
* @param options.time - Time filter for top sort (hour, day, week, month, year, all).
|
|
3397
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3398
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3399
|
+
* @returns Posts linking to the domain with pagination metadata.
|
|
3400
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3401
|
+
* @throws ValidationError - If the parameters are invalid.
|
|
3402
|
+
*
|
|
3403
|
+
* @example
|
|
3404
|
+
* ```typescript
|
|
3405
|
+
* const results = await client.reddit.search.domainPosts({
|
|
3406
|
+
* domain: "github.com",
|
|
3407
|
+
* sort: "top",
|
|
3408
|
+
* time: "week",
|
|
3409
|
+
* limit: 25,
|
|
3410
|
+
* });
|
|
3411
|
+
* for (const post of results.posts) {
|
|
3412
|
+
* console.log(`r/${post.subreddit}: ${post.title}`);
|
|
3413
|
+
* }
|
|
3414
|
+
* ```
|
|
3415
|
+
*/
|
|
3416
|
+
async domainPosts(options) {
|
|
3417
|
+
return this.client.request(
|
|
3418
|
+
"/v1/reddit/search/domain",
|
|
3419
|
+
{
|
|
3420
|
+
params: {
|
|
3421
|
+
domain: options.domain,
|
|
3422
|
+
sort: options.sort,
|
|
3423
|
+
time: options.time,
|
|
3424
|
+
after: options.after,
|
|
3425
|
+
limit: options.limit
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
);
|
|
3429
|
+
}
|
|
3430
|
+
};
|
|
3431
|
+
|
|
3432
|
+
// src/reddit/posts.ts
|
|
3433
|
+
var PostsClient = class {
|
|
3434
|
+
client;
|
|
3435
|
+
constructor(client) {
|
|
3436
|
+
this.client = client;
|
|
3437
|
+
}
|
|
3438
|
+
/**
|
|
3439
|
+
* Get trending/hot posts from Reddit or a specific subreddit.
|
|
3440
|
+
*
|
|
3441
|
+
* @param options - Request parameters.
|
|
3442
|
+
* @param options.subreddit - Subreddit name (without r/). If omitted, returns site-wide posts.
|
|
3443
|
+
* @param options.sort - Sort order (hot, new, top, rising, controversial).
|
|
3444
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3445
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3446
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3447
|
+
* @returns Trending posts with pagination metadata.
|
|
3448
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3449
|
+
*
|
|
3450
|
+
* @example
|
|
3451
|
+
* ```typescript
|
|
3452
|
+
* const results = await client.reddit.posts.trending({
|
|
3453
|
+
* subreddit: "worldnews",
|
|
3454
|
+
* sort: "hot",
|
|
3455
|
+
* limit: 25,
|
|
3456
|
+
* });
|
|
3457
|
+
* for (const post of results.posts) {
|
|
3458
|
+
* console.log(`${post.title} (${post.num_comments} comments)`);
|
|
3459
|
+
* }
|
|
3460
|
+
* ```
|
|
3461
|
+
*/
|
|
3462
|
+
async trending(options = {}) {
|
|
3463
|
+
return this.client.request("/v1/reddit/posts", {
|
|
3464
|
+
params: {
|
|
3465
|
+
subreddit: options.subreddit,
|
|
3466
|
+
sort: options.sort,
|
|
3467
|
+
time: options.time,
|
|
3468
|
+
after: options.after,
|
|
3469
|
+
limit: options.limit
|
|
3470
|
+
}
|
|
3471
|
+
});
|
|
3472
|
+
}
|
|
3473
|
+
/**
|
|
3474
|
+
* Get full details of a single Reddit post.
|
|
3475
|
+
*
|
|
3476
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
3477
|
+
* @param options - Optional parameters.
|
|
3478
|
+
* @param options.subreddit - Subreddit name (helps resolve the post URL).
|
|
3479
|
+
* @returns Full post details.
|
|
3480
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
3481
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3482
|
+
*
|
|
3483
|
+
* @example
|
|
3484
|
+
* ```typescript
|
|
3485
|
+
* const response = await client.reddit.posts.get("abc123", { subreddit: "programming" });
|
|
3486
|
+
* const { post } = response;
|
|
3487
|
+
* console.log(`${post.title} by u/${post.author}`);
|
|
3488
|
+
* console.log(`Score: ${post.score}, Comments: ${post.num_comments}`);
|
|
3489
|
+
* ```
|
|
3490
|
+
*/
|
|
3491
|
+
async get(postId, options = {}) {
|
|
3492
|
+
return this.client.request(
|
|
3493
|
+
`/v1/reddit/posts/${postId}`,
|
|
3494
|
+
{ params: { subreddit: options.subreddit } }
|
|
3495
|
+
);
|
|
3496
|
+
}
|
|
3497
|
+
/**
|
|
3498
|
+
* Get comments for a Reddit post.
|
|
3499
|
+
*
|
|
3500
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
3501
|
+
* @param options - Optional parameters.
|
|
3502
|
+
* @param options.subreddit - Subreddit name (helps resolve the post URL).
|
|
3503
|
+
* @param options.sort - Comment sort order (confidence, top, new, controversial, old, qa).
|
|
3504
|
+
* @param options.depth - Maximum comment tree depth.
|
|
3505
|
+
* @param options.limit - Number of top-level comments to return.
|
|
3506
|
+
* @returns Post details and nested comment tree.
|
|
3507
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
3508
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3509
|
+
*
|
|
3510
|
+
* @example
|
|
3511
|
+
* ```typescript
|
|
3512
|
+
* const response = await client.reddit.posts.comments("abc123", {
|
|
3513
|
+
* subreddit: "programming",
|
|
3514
|
+
* sort: "top",
|
|
3515
|
+
* limit: 50,
|
|
3516
|
+
* });
|
|
3517
|
+
* for (const comment of response.comments) {
|
|
3518
|
+
* console.log(`u/${comment.author}: ${comment.body.slice(0, 100)}`);
|
|
3519
|
+
* }
|
|
3520
|
+
* ```
|
|
3521
|
+
*/
|
|
3522
|
+
async comments(postId, options = {}) {
|
|
3523
|
+
return this.client.request(
|
|
3524
|
+
`/v1/reddit/posts/${postId}/comments`,
|
|
3525
|
+
{
|
|
3526
|
+
params: {
|
|
3527
|
+
subreddit: options.subreddit,
|
|
3528
|
+
sort: options.sort,
|
|
3529
|
+
depth: options.depth,
|
|
3530
|
+
limit: options.limit
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
);
|
|
3534
|
+
}
|
|
3535
|
+
/**
|
|
3536
|
+
* Get cross-posts and duplicate submissions of a Reddit post.
|
|
3537
|
+
*
|
|
3538
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
3539
|
+
* @param options - Optional parameters.
|
|
3540
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3541
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3542
|
+
* @returns The original post and its duplicate submissions.
|
|
3543
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
3544
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3545
|
+
*
|
|
3546
|
+
* @example
|
|
3547
|
+
* ```typescript
|
|
3548
|
+
* const response = await client.reddit.posts.duplicates("abc123");
|
|
3549
|
+
* console.log(`Original: ${response.post.title}`);
|
|
3550
|
+
* console.log(`Cross-posted ${response.duplicates.length} times`);
|
|
3551
|
+
* for (const dupe of response.duplicates) {
|
|
3552
|
+
* console.log(` r/${dupe.subreddit}: ${dupe.score} points`);
|
|
3553
|
+
* }
|
|
3554
|
+
* ```
|
|
3555
|
+
*/
|
|
3556
|
+
async duplicates(postId, options = {}) {
|
|
3557
|
+
return this.client.request(
|
|
3558
|
+
`/v1/reddit/posts/${postId}/duplicates`,
|
|
3559
|
+
{
|
|
3560
|
+
params: {
|
|
3561
|
+
after: options.after,
|
|
3562
|
+
limit: options.limit
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3565
|
+
);
|
|
3566
|
+
}
|
|
3567
|
+
};
|
|
3568
|
+
|
|
3569
|
+
// src/reddit/subreddits.ts
|
|
3570
|
+
var SubredditsClient = class {
|
|
3571
|
+
client;
|
|
3572
|
+
constructor(client) {
|
|
3573
|
+
this.client = client;
|
|
3574
|
+
}
|
|
3575
|
+
/**
|
|
3576
|
+
* Get a subreddit's full details and metadata.
|
|
3577
|
+
*
|
|
3578
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3579
|
+
* @returns Full subreddit details.
|
|
3580
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3581
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3582
|
+
*
|
|
3583
|
+
* @example
|
|
3584
|
+
* ```typescript
|
|
3585
|
+
* const response = await client.reddit.subreddits.get("javascript");
|
|
3586
|
+
* const { subreddit } = response;
|
|
3587
|
+
* console.log(`${subreddit.title}: ${subreddit.subscribers.toLocaleString()} members`);
|
|
3588
|
+
* console.log(`Description: ${subreddit.public_description}`);
|
|
3589
|
+
* ```
|
|
3590
|
+
*/
|
|
3591
|
+
async get(subreddit) {
|
|
3592
|
+
return this.client.request(
|
|
3593
|
+
`/v1/reddit/subreddits/${subreddit}`
|
|
3594
|
+
);
|
|
3595
|
+
}
|
|
3596
|
+
/**
|
|
3597
|
+
* Get posts from a subreddit.
|
|
3598
|
+
*
|
|
3599
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3600
|
+
* @param options - Optional parameters.
|
|
3601
|
+
* @param options.sort - Sort order (hot, new, top, rising, controversial).
|
|
3602
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3603
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3604
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3605
|
+
* @returns Subreddit posts with pagination metadata.
|
|
3606
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3607
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3608
|
+
*
|
|
3609
|
+
* @example
|
|
3610
|
+
* ```typescript
|
|
3611
|
+
* const response = await client.reddit.subreddits.posts("typescript", {
|
|
3612
|
+
* sort: "top",
|
|
3613
|
+
* time: "week",
|
|
3614
|
+
* limit: 25,
|
|
3615
|
+
* });
|
|
3616
|
+
* for (const post of response.posts) {
|
|
3617
|
+
* console.log(`${post.title} — ${post.score} pts`);
|
|
3618
|
+
* }
|
|
3619
|
+
* ```
|
|
3620
|
+
*/
|
|
3621
|
+
async posts(subreddit, options = {}) {
|
|
3622
|
+
return this.client.request(
|
|
3623
|
+
`/v1/reddit/subreddits/${subreddit}/posts`,
|
|
3624
|
+
{
|
|
3625
|
+
params: {
|
|
3626
|
+
sort: options.sort,
|
|
3627
|
+
time: options.time,
|
|
3628
|
+
after: options.after,
|
|
3629
|
+
limit: options.limit
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
/**
|
|
3635
|
+
* Get the rules for a subreddit.
|
|
3636
|
+
*
|
|
3637
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3638
|
+
* @returns List of subreddit rules.
|
|
3639
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3640
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3641
|
+
*
|
|
3642
|
+
* @example
|
|
3643
|
+
* ```typescript
|
|
3644
|
+
* const response = await client.reddit.subreddits.rules("AskReddit");
|
|
3645
|
+
* for (const rule of response.rules) {
|
|
3646
|
+
* console.log(`${rule.priority}. ${rule.short_name}`);
|
|
3647
|
+
* console.log(` ${rule.description}`);
|
|
3648
|
+
* }
|
|
3649
|
+
* ```
|
|
3650
|
+
*/
|
|
3651
|
+
async rules(subreddit) {
|
|
3652
|
+
return this.client.request(
|
|
3653
|
+
`/v1/reddit/subreddits/${subreddit}/rules`
|
|
3654
|
+
);
|
|
3655
|
+
}
|
|
3656
|
+
/**
|
|
3657
|
+
* Get the moderators of a subreddit.
|
|
3658
|
+
*
|
|
3659
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3660
|
+
* @param options - Optional parameters.
|
|
3661
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3662
|
+
* @param options.limit - Number of results to return.
|
|
3663
|
+
* @returns List of moderators with pagination metadata.
|
|
3664
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3665
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3666
|
+
*
|
|
3667
|
+
* @example
|
|
3668
|
+
* ```typescript
|
|
3669
|
+
* const response = await client.reddit.subreddits.moderators("programming");
|
|
3670
|
+
* for (const mod of response.moderators) {
|
|
3671
|
+
* console.log(`u/${mod.name}: [${mod.mod_permissions.join(", ")}]`);
|
|
3672
|
+
* }
|
|
3673
|
+
* ```
|
|
3674
|
+
*/
|
|
3675
|
+
async moderators(subreddit, options = {}) {
|
|
3676
|
+
return this.client.request(
|
|
3677
|
+
`/v1/reddit/subreddits/${subreddit}/moderators`,
|
|
3678
|
+
{
|
|
3679
|
+
params: {
|
|
3680
|
+
after: options.after,
|
|
3681
|
+
limit: options.limit
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
);
|
|
3685
|
+
}
|
|
3686
|
+
/**
|
|
3687
|
+
* List all wiki pages in a subreddit.
|
|
3688
|
+
*
|
|
3689
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3690
|
+
* @returns List of wiki page slugs.
|
|
3691
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3692
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3693
|
+
*
|
|
3694
|
+
* @example
|
|
3695
|
+
* ```typescript
|
|
3696
|
+
* const response = await client.reddit.subreddits.wikiPages("rust");
|
|
3697
|
+
* for (const page of response.pages) {
|
|
3698
|
+
* console.log(`/r/rust/wiki/${page}`);
|
|
3699
|
+
* }
|
|
3700
|
+
* ```
|
|
3701
|
+
*/
|
|
3702
|
+
async wikiPages(subreddit) {
|
|
3703
|
+
return this.client.request(
|
|
3704
|
+
`/v1/reddit/subreddits/${subreddit}/wiki`
|
|
3705
|
+
);
|
|
3706
|
+
}
|
|
3707
|
+
/**
|
|
3708
|
+
* Get the content of a specific wiki page in a subreddit.
|
|
3709
|
+
*
|
|
3710
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3711
|
+
* @param page - Wiki page slug (e.g. "index", "faq").
|
|
3712
|
+
* @returns Wiki page content and metadata.
|
|
3713
|
+
* @throws NotFoundError - If the subreddit or wiki page doesn't exist.
|
|
3714
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3715
|
+
*
|
|
3716
|
+
* @example
|
|
3717
|
+
* ```typescript
|
|
3718
|
+
* const response = await client.reddit.subreddits.wikiPage("learnprogramming", "faq");
|
|
3719
|
+
* console.log(`Last edited by: u/${response.page.revision_by}`);
|
|
3720
|
+
* console.log(response.page.content_md);
|
|
3721
|
+
* ```
|
|
3722
|
+
*/
|
|
3723
|
+
async wikiPage(subreddit, page) {
|
|
3724
|
+
return this.client.request(
|
|
3725
|
+
`/v1/reddit/subreddits/${subreddit}/wiki/${page}`
|
|
3726
|
+
);
|
|
3727
|
+
}
|
|
3728
|
+
/**
|
|
3729
|
+
* Get the most popular subreddits on Reddit.
|
|
3730
|
+
*
|
|
3731
|
+
* @param options - Optional parameters.
|
|
3732
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3733
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3734
|
+
* @returns Popular subreddits with pagination metadata.
|
|
3735
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3736
|
+
*
|
|
3737
|
+
* @example
|
|
3738
|
+
* ```typescript
|
|
3739
|
+
* const response = await client.reddit.subreddits.popular({ limit: 20 });
|
|
3740
|
+
* for (const sub of response.subreddits) {
|
|
3741
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
3742
|
+
* }
|
|
3743
|
+
* ```
|
|
3744
|
+
*/
|
|
3745
|
+
async popular(options = {}) {
|
|
3746
|
+
return this.client.request(
|
|
3747
|
+
"/v1/reddit/subreddits/popular",
|
|
3748
|
+
{
|
|
3749
|
+
params: {
|
|
3750
|
+
after: options.after,
|
|
3751
|
+
limit: options.limit
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
);
|
|
3755
|
+
}
|
|
3756
|
+
/**
|
|
3757
|
+
* Get newly created subreddits on Reddit.
|
|
3758
|
+
*
|
|
3759
|
+
* @param options - Optional parameters.
|
|
3760
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3761
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3762
|
+
* @returns New subreddits with pagination metadata.
|
|
3763
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3764
|
+
*
|
|
3765
|
+
* @example
|
|
3766
|
+
* ```typescript
|
|
3767
|
+
* const response = await client.reddit.subreddits.newSubreddits({ limit: 20 });
|
|
3768
|
+
* for (const sub of response.subreddits) {
|
|
3769
|
+
* console.log(`r/${sub.display_name} (created: ${new Date(sub.created_utc * 1000).toLocaleDateString()})`);
|
|
3770
|
+
* }
|
|
3771
|
+
* ```
|
|
3772
|
+
*/
|
|
3773
|
+
async newSubreddits(options = {}) {
|
|
3774
|
+
return this.client.request(
|
|
3775
|
+
"/v1/reddit/subreddits/new",
|
|
3776
|
+
{
|
|
3777
|
+
params: {
|
|
3778
|
+
after: options.after,
|
|
3779
|
+
limit: options.limit
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
);
|
|
3783
|
+
}
|
|
3784
|
+
};
|
|
3785
|
+
|
|
3786
|
+
// src/reddit/users.ts
|
|
3787
|
+
var UsersClient3 = class {
|
|
3788
|
+
client;
|
|
3789
|
+
constructor(client) {
|
|
3790
|
+
this.client = client;
|
|
3791
|
+
}
|
|
3792
|
+
/**
|
|
3793
|
+
* Get a Reddit user's profile.
|
|
3794
|
+
*
|
|
3795
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3796
|
+
* @returns The user profile response.
|
|
3797
|
+
* @throws NotFoundError - If the user doesn't exist or is suspended.
|
|
3798
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3799
|
+
*
|
|
3800
|
+
* @example
|
|
3801
|
+
* ```typescript
|
|
3802
|
+
* const response = await client.reddit.users.get("spez");
|
|
3803
|
+
* const { user } = response;
|
|
3804
|
+
* console.log(`u/${user.name}`);
|
|
3805
|
+
* console.log(`Karma: ${user.total_karma.toLocaleString()} (${user.link_karma} post, ${user.comment_karma} comment)`);
|
|
3806
|
+
* console.log(`Account age: ${new Date(user.created_utc * 1000).toLocaleDateString()}`);
|
|
3807
|
+
* ```
|
|
3808
|
+
*/
|
|
3809
|
+
async get(username) {
|
|
3810
|
+
return this.client.request(
|
|
3811
|
+
`/v1/reddit/users/${username}`
|
|
3812
|
+
);
|
|
3813
|
+
}
|
|
3814
|
+
/**
|
|
3815
|
+
* Get posts submitted by a Reddit user.
|
|
3816
|
+
*
|
|
3817
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3818
|
+
* @param options - Optional parameters.
|
|
3819
|
+
* @param options.sort - Sort order (hot, new, top, controversial).
|
|
3820
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3821
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3822
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3823
|
+
* @returns The user's posts with pagination metadata.
|
|
3824
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3825
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3826
|
+
*
|
|
3827
|
+
* @example
|
|
3828
|
+
* ```typescript
|
|
3829
|
+
* const response = await client.reddit.users.posts("spez", {
|
|
3830
|
+
* sort: "top",
|
|
3831
|
+
* time: "all",
|
|
3832
|
+
* limit: 25,
|
|
3833
|
+
* });
|
|
3834
|
+
* for (const post of response.posts) {
|
|
3835
|
+
* console.log(`r/${post.subreddit}: ${post.title} (${post.score} pts)`);
|
|
3836
|
+
* }
|
|
3837
|
+
* ```
|
|
3838
|
+
*/
|
|
3839
|
+
async posts(username, options = {}) {
|
|
3840
|
+
return this.client.request(
|
|
3841
|
+
`/v1/reddit/users/${username}/posts`,
|
|
3842
|
+
{
|
|
3843
|
+
params: {
|
|
3844
|
+
sort: options.sort,
|
|
3845
|
+
time: options.time,
|
|
3846
|
+
after: options.after,
|
|
3847
|
+
limit: options.limit
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3852
|
+
/**
|
|
3853
|
+
* Get comments made by a Reddit user.
|
|
3854
|
+
*
|
|
3855
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3856
|
+
* @param options - Optional parameters.
|
|
3857
|
+
* @param options.sort - Sort order (hot, new, top, controversial).
|
|
3858
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3859
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3860
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3861
|
+
* @returns The user's comments with pagination metadata.
|
|
3862
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3863
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3864
|
+
*
|
|
3865
|
+
* @example
|
|
3866
|
+
* ```typescript
|
|
3867
|
+
* const response = await client.reddit.users.comments("spez", {
|
|
3868
|
+
* sort: "new",
|
|
3869
|
+
* limit: 50,
|
|
3870
|
+
* });
|
|
3871
|
+
* for (const comment of response.comments) {
|
|
3872
|
+
* console.log(`r/${comment.subreddit}: ${comment.body.slice(0, 80)}`);
|
|
3873
|
+
* }
|
|
3874
|
+
* ```
|
|
3875
|
+
*/
|
|
3876
|
+
async comments(username, options = {}) {
|
|
3877
|
+
return this.client.request(
|
|
3878
|
+
`/v1/reddit/users/${username}/comments`,
|
|
3879
|
+
{
|
|
3880
|
+
params: {
|
|
3881
|
+
sort: options.sort,
|
|
3882
|
+
time: options.time,
|
|
3883
|
+
after: options.after,
|
|
3884
|
+
limit: options.limit
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3887
|
+
);
|
|
3888
|
+
}
|
|
3889
|
+
/**
|
|
3890
|
+
* Get subreddits moderated by a Reddit user.
|
|
3891
|
+
*
|
|
3892
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3893
|
+
* @returns Subreddits moderated by the user.
|
|
3894
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3895
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3896
|
+
*
|
|
3897
|
+
* @example
|
|
3898
|
+
* ```typescript
|
|
3899
|
+
* const response = await client.reddit.users.moderated("spez");
|
|
3900
|
+
* for (const sub of response.subreddits) {
|
|
3901
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
3902
|
+
* }
|
|
3903
|
+
* ```
|
|
3904
|
+
*/
|
|
3905
|
+
async moderated(username) {
|
|
3906
|
+
return this.client.request(
|
|
3907
|
+
`/v1/reddit/users/${username}/moderated`
|
|
3908
|
+
);
|
|
3909
|
+
}
|
|
3910
|
+
/**
|
|
3911
|
+
* Get trophies awarded to a Reddit user.
|
|
3912
|
+
*
|
|
3913
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3914
|
+
* @returns List of trophies awarded to the user.
|
|
3915
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3916
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3917
|
+
*
|
|
3918
|
+
* @example
|
|
3919
|
+
* ```typescript
|
|
3920
|
+
* const response = await client.reddit.users.trophies("spez");
|
|
3921
|
+
* for (const trophy of response.trophies) {
|
|
3922
|
+
* console.log(`${trophy.name}${trophy.description ? `: ${trophy.description}` : ""}`);
|
|
3923
|
+
* }
|
|
3924
|
+
* ```
|
|
3925
|
+
*/
|
|
3926
|
+
async trophies(username) {
|
|
3927
|
+
return this.client.request(
|
|
3928
|
+
`/v1/reddit/users/${username}/trophies`
|
|
3929
|
+
);
|
|
3930
|
+
}
|
|
3931
|
+
};
|
|
3932
|
+
|
|
3933
|
+
// src/reddit/client.ts
|
|
3934
|
+
var RedditClient = class {
|
|
3935
|
+
/** Client for search operations (posts, subreddits, users, domain posts) */
|
|
3936
|
+
search;
|
|
3937
|
+
/** Client for post operations (trending, details, comments, duplicates) */
|
|
3938
|
+
posts;
|
|
3939
|
+
/** Client for subreddit operations (details, posts, rules, moderators, wiki) */
|
|
3940
|
+
subreddits;
|
|
3941
|
+
/** Client for user operations (profile, posts, comments, moderated, trophies) */
|
|
3942
|
+
users;
|
|
3943
|
+
/**
|
|
3944
|
+
* Create a new Reddit client.
|
|
3945
|
+
*
|
|
3946
|
+
* @param client - The base HTTP client for making requests.
|
|
3947
|
+
*/
|
|
3948
|
+
constructor(client) {
|
|
3949
|
+
this.search = new SearchClient3(client);
|
|
3950
|
+
this.posts = new PostsClient(client);
|
|
3951
|
+
this.subreddits = new SubredditsClient(client);
|
|
3952
|
+
this.users = new UsersClient3(client);
|
|
2524
3953
|
}
|
|
2525
3954
|
};
|
|
2526
3955
|
|
|
@@ -2531,6 +3960,12 @@ var ScrapeBadger = class {
|
|
|
2531
3960
|
twitter;
|
|
2532
3961
|
/** Web scraping API client */
|
|
2533
3962
|
web;
|
|
3963
|
+
/** Vinted scraper API client */
|
|
3964
|
+
vinted;
|
|
3965
|
+
/** Google Scraper API client — 19 Google product APIs */
|
|
3966
|
+
google;
|
|
3967
|
+
/** Reddit scraper API client */
|
|
3968
|
+
reddit;
|
|
2534
3969
|
/**
|
|
2535
3970
|
* Create a new ScrapeBadger client.
|
|
2536
3971
|
*
|
|
@@ -2567,6 +4002,9 @@ var ScrapeBadger = class {
|
|
|
2567
4002
|
this.baseClient = new BaseClient(resolvedConfig);
|
|
2568
4003
|
this.twitter = new TwitterClient(this.baseClient);
|
|
2569
4004
|
this.web = new WebClient(this.baseClient);
|
|
4005
|
+
this.vinted = new VintedClient(this.baseClient);
|
|
4006
|
+
this.google = new GoogleClient(this.baseClient);
|
|
4007
|
+
this.reddit = new RedditClient(this.baseClient);
|
|
2570
4008
|
}
|
|
2571
4009
|
};
|
|
2572
4010
|
|
|
@@ -2575,10 +4013,34 @@ exports.AuthenticationError = AuthenticationError;
|
|
|
2575
4013
|
exports.CommunitiesClient = CommunitiesClient;
|
|
2576
4014
|
exports.ConflictError = ConflictError;
|
|
2577
4015
|
exports.GeoClient = GeoClient;
|
|
4016
|
+
exports.GoogleAiModeClient = AiModeClient;
|
|
4017
|
+
exports.GoogleAutocompleteClient = AutocompleteClient;
|
|
4018
|
+
exports.GoogleClient = GoogleClient;
|
|
4019
|
+
exports.GoogleFinanceClient = FinanceClient;
|
|
4020
|
+
exports.GoogleFlightsClient = FlightsClient;
|
|
4021
|
+
exports.GoogleHotelsClient = HotelsClient;
|
|
4022
|
+
exports.GoogleImagesClient = ImagesClient;
|
|
4023
|
+
exports.GoogleJobsClient = JobsClient;
|
|
4024
|
+
exports.GoogleLensClient = LensClient;
|
|
4025
|
+
exports.GoogleMapsClient = MapsClient;
|
|
4026
|
+
exports.GoogleNewsClient = NewsClient;
|
|
4027
|
+
exports.GooglePatentsClient = PatentsClient;
|
|
4028
|
+
exports.GoogleProductsClient = ProductsClient;
|
|
4029
|
+
exports.GoogleScholarClient = ScholarClient;
|
|
4030
|
+
exports.GoogleSearchClient = SearchClient2;
|
|
4031
|
+
exports.GoogleShoppingClient = ShoppingClient;
|
|
4032
|
+
exports.GoogleShortsClient = ShortsClient;
|
|
4033
|
+
exports.GoogleTrendsClient = TrendsClient2;
|
|
4034
|
+
exports.GoogleVideosClient = VideosClient;
|
|
2578
4035
|
exports.InsufficientCreditsError = InsufficientCreditsError;
|
|
2579
4036
|
exports.ListsClient = ListsClient;
|
|
2580
4037
|
exports.NotFoundError = NotFoundError;
|
|
2581
4038
|
exports.RateLimitError = RateLimitError;
|
|
4039
|
+
exports.RedditClient = RedditClient;
|
|
4040
|
+
exports.RedditPostsClient = PostsClient;
|
|
4041
|
+
exports.RedditSearchClient = SearchClient3;
|
|
4042
|
+
exports.RedditSubredditsClient = SubredditsClient;
|
|
4043
|
+
exports.RedditUsersClient = UsersClient3;
|
|
2582
4044
|
exports.ScrapeBadger = ScrapeBadger;
|
|
2583
4045
|
exports.ScrapeBadgerError = ScrapeBadgerError;
|
|
2584
4046
|
exports.ServerError = ServerError;
|
|
@@ -2590,6 +4052,11 @@ exports.TweetsClient = TweetsClient;
|
|
|
2590
4052
|
exports.TwitterClient = TwitterClient;
|
|
2591
4053
|
exports.UsersClient = UsersClient;
|
|
2592
4054
|
exports.ValidationError = ValidationError;
|
|
4055
|
+
exports.VintedClient = VintedClient;
|
|
4056
|
+
exports.VintedItemsClient = ItemsClient;
|
|
4057
|
+
exports.VintedReferenceClient = ReferenceClient;
|
|
4058
|
+
exports.VintedSearchClient = SearchClient;
|
|
4059
|
+
exports.VintedUsersClient = UsersClient2;
|
|
2593
4060
|
exports.WebClient = WebClient;
|
|
2594
4061
|
exports.WebSocketStreamError = WebSocketStreamError;
|
|
2595
4062
|
exports.collectAll = collectAll;
|