scrapebadger 0.2.0 → 0.3.1

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.
@@ -1,2 +1,2 @@
1
- export { _ as ApiResponse, ae as BillingLog, af as BillingLogList, j as CommunitiesClient, J as Community, E as CommunityBanner, K as CommunityMember, F as CommunityRule, p as CommunityTweetType, ag as ConnectOptions, a6 as ConnectedEvent, a3 as CreateMonitorParams, ac as DeliveryLog, ad as DeliveryLogList, a9 as ErrorEvent, aj as FilterRuleCreate, ao as FilterRuleDeliveryLog, ap as FilterRuleDeliveryLogListResponse, am as FilterRuleListResponse, al as FilterRulePricingTier, aq as FilterRulePricingTiersResponse, ai as FilterRuleResponse, ah as FilterRuleStatus, ak as FilterRuleUpdate, an as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, D as List, $ as ListResponse, L as ListsClient, X as Location, M as Media, a0 as MonitorStatus, a7 as PingEvent, Z as Place, Y as PlaceTrends, r as Poll, q as PollOption, Q as QueryType, m as StreamClient, n as StreamEmitter, aa as StreamEvent, ab as StreamEventType, a1 as StreamMonitor, a2 as StreamMonitorList, a5 as StreamTweet, O as Trend, o as TrendCategory, k as TrendsClient, w as Tweet, a8 as TweetEvent, u as TweetPlace, i as TweetsClient, T as TwitterClient, a4 as UpdateMonitorParams, s as Url, x as User, y as UserAbout, z as UserIds, t as UserMention, U as UsersClient, v as verifyWebhookSignature } from '../index-BbCkdZXy.cjs';
1
+ export { _ as ApiResponse, ae as BillingLog, af as BillingLogList, j as CommunitiesClient, J as Community, E as CommunityBanner, K as CommunityMember, F as CommunityRule, p as CommunityTweetType, ag as ConnectOptions, a6 as ConnectedEvent, a3 as CreateMonitorParams, ac as DeliveryLog, ad as DeliveryLogList, a9 as ErrorEvent, aj as FilterRuleCreate, ao as FilterRuleDeliveryLog, ap as FilterRuleDeliveryLogListResponse, am as FilterRuleListResponse, al as FilterRulePricingTier, aq as FilterRulePricingTiersResponse, ai as FilterRuleResponse, ah as FilterRuleStatus, ak as FilterRuleUpdate, an as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, D as List, $ as ListResponse, L as ListsClient, X as Location, M as Media, a0 as MonitorStatus, a7 as PingEvent, Z as Place, Y as PlaceTrends, r as Poll, q as PollOption, Q as QueryType, m as StreamClient, n as StreamEmitter, aa as StreamEvent, ab as StreamEventType, a1 as StreamMonitor, a2 as StreamMonitorList, a5 as StreamTweet, O as Trend, o as TrendCategory, k as TrendsClient, w as Tweet, a8 as TweetEvent, u as TweetPlace, i as TweetsClient, T as TwitterClient, a4 as UpdateMonitorParams, s as Url, x as User, y as UserAbout, z as UserIds, t as UserMention, U as UsersClient, v as verifyWebhookSignature } from '../index-Cg0sNluO.cjs';
2
2
  import 'node:events';
@@ -1,2 +1,2 @@
1
- export { _ as ApiResponse, ae as BillingLog, af as BillingLogList, j as CommunitiesClient, J as Community, E as CommunityBanner, K as CommunityMember, F as CommunityRule, p as CommunityTweetType, ag as ConnectOptions, a6 as ConnectedEvent, a3 as CreateMonitorParams, ac as DeliveryLog, ad as DeliveryLogList, a9 as ErrorEvent, aj as FilterRuleCreate, ao as FilterRuleDeliveryLog, ap as FilterRuleDeliveryLogListResponse, am as FilterRuleListResponse, al as FilterRulePricingTier, aq as FilterRulePricingTiersResponse, ai as FilterRuleResponse, ah as FilterRuleStatus, ak as FilterRuleUpdate, an as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, D as List, $ as ListResponse, L as ListsClient, X as Location, M as Media, a0 as MonitorStatus, a7 as PingEvent, Z as Place, Y as PlaceTrends, r as Poll, q as PollOption, Q as QueryType, m as StreamClient, n as StreamEmitter, aa as StreamEvent, ab as StreamEventType, a1 as StreamMonitor, a2 as StreamMonitorList, a5 as StreamTweet, O as Trend, o as TrendCategory, k as TrendsClient, w as Tweet, a8 as TweetEvent, u as TweetPlace, i as TweetsClient, T as TwitterClient, a4 as UpdateMonitorParams, s as Url, x as User, y as UserAbout, z as UserIds, t as UserMention, U as UsersClient, v as verifyWebhookSignature } from '../index-BbCkdZXy.js';
1
+ export { _ as ApiResponse, ae as BillingLog, af as BillingLogList, j as CommunitiesClient, J as Community, E as CommunityBanner, K as CommunityMember, F as CommunityRule, p as CommunityTweetType, ag as ConnectOptions, a6 as ConnectedEvent, a3 as CreateMonitorParams, ac as DeliveryLog, ad as DeliveryLogList, a9 as ErrorEvent, aj as FilterRuleCreate, ao as FilterRuleDeliveryLog, ap as FilterRuleDeliveryLogListResponse, am as FilterRuleListResponse, al as FilterRulePricingTier, aq as FilterRulePricingTiersResponse, ai as FilterRuleResponse, ah as FilterRuleStatus, ak as FilterRuleUpdate, an as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, D as List, $ as ListResponse, L as ListsClient, X as Location, M as Media, a0 as MonitorStatus, a7 as PingEvent, Z as Place, Y as PlaceTrends, r as Poll, q as PollOption, Q as QueryType, m as StreamClient, n as StreamEmitter, aa as StreamEvent, ab as StreamEventType, a1 as StreamMonitor, a2 as StreamMonitorList, a5 as StreamTweet, O as Trend, o as TrendCategory, k as TrendsClient, w as Tweet, a8 as TweetEvent, u as TweetPlace, i as TweetsClient, T as TwitterClient, a4 as UpdateMonitorParams, s as Url, x as User, y as UserAbout, z as UserIds, t as UserMention, U as UsersClient, v as verifyWebhookSignature } from '../index-Cg0sNluO.js';
2
2
  import 'node:events';
@@ -16,12 +16,26 @@ function createPaginatedResponse(data, cursor) {
16
16
  hasMore: !!cursor
17
17
  };
18
18
  }
19
+ var RATE_LIMIT_WARN_THRESHOLD = 0.2;
19
20
  async function* paginate(fetchPage, options = {}) {
20
21
  const { maxItems } = options;
21
22
  let cursor;
22
23
  let totalYielded = 0;
23
24
  do {
24
- const response = await fetchPage(cursor);
25
+ const { response, rateLimit } = await fetchPage(cursor);
26
+ if (rateLimit) {
27
+ const { limit, remaining, reset } = rateLimit;
28
+ if (limit > 0 && remaining / limit < RATE_LIMIT_WARN_THRESHOLD) {
29
+ const nowSec = Date.now() / 1e3;
30
+ const windowRemainingSec = Math.max(reset - nowSec, 1);
31
+ const delayMs = remaining > 0 ? windowRemainingSec / remaining * 1e3 : windowRemainingSec * 1e3;
32
+ const resetInSec = Math.round(windowRemainingSec);
33
+ console.warn(
34
+ `\x1B[33m\u26A0 ScrapeBadger: Rate limit: ${remaining}/${limit} remaining (resets in ${resetInSec}s), throttling pagination\x1B[0m`
35
+ );
36
+ await sleep(delayMs);
37
+ }
38
+ }
25
39
  for (const item of response.data) {
26
40
  yield item;
27
41
  totalYielded++;
@@ -32,6 +46,9 @@ async function* paginate(fetchPage, options = {}) {
32
46
  cursor = response.nextCursor;
33
47
  } while (cursor);
34
48
  }
49
+ function sleep(ms) {
50
+ return new Promise((resolve) => setTimeout(resolve, ms));
51
+ }
35
52
 
36
53
  // src/twitter/tweets.ts
37
54
  var TweetsClient = class {
@@ -229,7 +246,8 @@ var TweetsClient = class {
229
246
  */
230
247
  async *getQuotesAll(tweetId, options = {}) {
231
248
  const fetchPage = async (cursor) => {
232
- return this.getQuotes(tweetId, { ...options, cursor });
249
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/tweets/tweet/${tweetId}/quotes`, { params: { cursor } });
250
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
233
251
  };
234
252
  yield* paginate(fetchPage, options);
235
253
  }
@@ -296,7 +314,15 @@ var TweetsClient = class {
296
314
  */
297
315
  async *searchAll(query, options = {}) {
298
316
  const fetchPage = async (cursor) => {
299
- return this.search(query, { ...options, cursor });
317
+ const { data, rateLimit } = await this.client.requestWithHeaders("/v1/twitter/tweets/advanced_search", {
318
+ params: {
319
+ query,
320
+ query_type: options.queryType ?? "Top",
321
+ count: options.count,
322
+ cursor
323
+ }
324
+ });
325
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
300
326
  };
301
327
  yield* paginate(fetchPage, options);
302
328
  }
@@ -340,7 +366,8 @@ var TweetsClient = class {
340
366
  */
341
367
  async *getUserTweetsAll(username, options = {}) {
342
368
  const fetchPage = async (cursor) => {
343
- return this.getUserTweets(username, { ...options, cursor });
369
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/latest_tweets`, { params: { cursor } });
370
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
344
371
  };
345
372
  yield* paginate(fetchPage, options);
346
373
  }
@@ -450,7 +477,8 @@ var UsersClient = class {
450
477
  */
451
478
  async *getFollowersAll(username, options = {}) {
452
479
  const fetchPage = async (cursor) => {
453
- return this.getFollowers(username, { ...options, cursor });
480
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/followers`, { params: { cursor } });
481
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
454
482
  };
455
483
  yield* paginate(fetchPage, options);
456
484
  }
@@ -485,7 +513,8 @@ var UsersClient = class {
485
513
  */
486
514
  async *getFollowingAll(username, options = {}) {
487
515
  const fetchPage = async (cursor) => {
488
- return this.getFollowing(username, { ...options, cursor });
516
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/followings`, { params: { cursor } });
517
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
489
518
  };
490
519
  yield* paginate(fetchPage, options);
491
520
  }
@@ -648,7 +677,8 @@ var UsersClient = class {
648
677
  */
649
678
  async *searchAll(query, options = {}) {
650
679
  const fetchPage = async (cursor) => {
651
- return this.search(query, { ...options, cursor });
680
+ const { data, rateLimit } = await this.client.requestWithHeaders("/v1/twitter/users/search_users", { params: { query, cursor } });
681
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
652
682
  };
653
683
  yield* paginate(fetchPage, options);
654
684
  }
@@ -708,7 +738,8 @@ var ListsClient = class {
708
738
  */
709
739
  async *getTweetsAll(listId, options = {}) {
710
740
  const fetchPage = async (cursor) => {
711
- return this.getTweets(listId, { ...options, cursor });
741
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/lists/${listId}/tweets`, { params: { cursor } });
742
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
712
743
  };
713
744
  yield* paginate(fetchPage, options);
714
745
  }
@@ -743,7 +774,8 @@ var ListsClient = class {
743
774
  */
744
775
  async *getMembersAll(listId, options = {}) {
745
776
  const fetchPage = async (cursor) => {
746
- return this.getMembers(listId, { ...options, cursor });
777
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/lists/${listId}/members`, { params: { cursor } });
778
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
747
779
  };
748
780
  yield* paginate(fetchPage, options);
749
781
  }
@@ -891,7 +923,14 @@ var CommunitiesClient = class {
891
923
  */
892
924
  async *getTweetsAll(communityId, options = {}) {
893
925
  const fetchPage = async (cursor) => {
894
- return this.getTweets(communityId, { ...options, cursor });
926
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/communities/${communityId}/tweets`, {
927
+ params: {
928
+ tweet_type: options.tweetType ?? "Top",
929
+ count: options.count ?? 40,
930
+ cursor
931
+ }
932
+ });
933
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
895
934
  };
896
935
  yield* paginate(fetchPage, options);
897
936
  }