diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3f9dfb8..7604eb2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,15 +10,6 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- - name: Set up Python
- uses: actions/setup-python@v3
- with:
- python-version: 3.x
-
- - name: Install dependencies
- run: |
- pip install tweepy
-
- name: Run tweet script
uses: ./
with:
diff --git a/README.md b/README.md
index b4295f8..2b17b3b 100644
--- a/README.md
+++ b/README.md
@@ -14,17 +14,8 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- - name: Set up Python
- uses: actions/setup-python@v3
- with:
- python-version: 3.x
-
- - name: Install dependencies
- run: |
- pip install tweepy
-
- name: Publish tweet
- uses: intelowlproject/twitter-post
+ uses: intelowlproject/twitter_post@main
with:
status: Add publish notes here
api_key: ${{ secrets.TWITTER_API_KEY}}
diff --git a/action.yml b/action.yml
index 1ad75ac..e8e64c4 100644
--- a/action.yml
+++ b/action.yml
@@ -24,25 +24,9 @@ outputs:
description: "Post's title"
runs:
- using: "composite"
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: 3.x
-
- - name: Install dependencies
- run: |
- pip install tweepy
- shell: bash
-
- - name: Run tweet script
- run: python3 publish.py ${{ inputs.api_key }} ${{ inputs.api_key_secret }} ${{ inputs.access_token }} ${{ inputs.access_token_secret }} "${{ inputs.status }}"
- shell: bash
+ using: "node16"
+ main: "index.js"
branding:
icon: "message-circle"
- color: "blue"
+ color: "blue"
\ No newline at end of file
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..e66b94f
--- /dev/null
+++ b/index.js
@@ -0,0 +1,28 @@
+const { TwitterApi } = require('twitter-api-v2');
+
+const {
+ INPUT_STATUS,
+ INPUT_API_KEY,
+ INPUT_API_KEY_SECRET,
+ INPUT_ACCESS_TOKEN,
+ INPUT_ACCESS_TOKEN_SECRET,
+} = process.env;
+
+(async () => {
+
+ try {
+ const userClient = new TwitterApi({
+ appKey: INPUT_API_KEY,
+ appSecret: INPUT_API_KEY_SECRET,
+ accessToken: INPUT_ACCESS_TOKEN,
+ accessSecret: INPUT_ACCESS_TOKEN_SECRET,
+ });
+
+ await userClient.v2.tweet(INPUT_STATUS);
+
+ } catch (err) {
+ console.log(err);
+ console.log(`::error ::${err.data}`);
+ }
+
+ })();
\ No newline at end of file
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
new file mode 100644
index 0000000..5c1b820
--- /dev/null
+++ b/node_modules/.package-lock.json
@@ -0,0 +1,13 @@
+{
+ "name": "twitter_post",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "node_modules/twitter-api-v2": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/twitter-api-v2/-/twitter-api-v2-1.15.1.tgz",
+ "integrity": "sha512-KNxoJL+sldWMI3AooPGcNkbP8awQai93d9xxsTurVPuUo/qnOUR3iO0XZTGC5sezdejHHqNyTwBAgGGw948MDg=="
+ }
+ }
+}
diff --git a/node_modules/twitter-api-v2/LICENSE b/node_modules/twitter-api-v2/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/node_modules/twitter-api-v2/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/node_modules/twitter-api-v2/README.md b/node_modules/twitter-api-v2/README.md
new file mode 100644
index 0000000..0a79ecd
--- /dev/null
+++ b/node_modules/twitter-api-v2/README.md
@@ -0,0 +1,139 @@
+# Twitter API v2
+
+[](https://developer.twitter.com/en/docs/twitter-api/early-access)
+[](https://developer.twitter.com/en/docs/twitter-api/v1)
+[](https://github.com/PLhery/node-twitter-api-v2)
+[](https://github.com/PLhery/node-twitter-api-v2/actions/workflows/CI.yml)
+[](https://bundlephobia.com/package/twitter-api-v2)
+
+Strongly typed, full-featured, light, versatile yet powerful Twitter API v1.1 and v2 client for Node.js.
+
+Main maintainer: [@alkihis](https://github.com/alkihis) -
+
+## Important Note
+
+Twitter will significantly reduce its API capabilities by end of April ([see this thread](https://twitter.com/TwitterDev/status/1641222782594990080)).
+
+This change has major implications, and as a result, this library may no longer be maintained.
+
+We are disappointed and discouraged by the recent turn of events at Twitter since the takeover by Elon Musk. We are saddened to see that much of the hard work of the past few years on the API, led by an amazing team including @andypiper, has been shelved.
+
+For a more detailed explanation, please see [this discussion](https://github.com/PLhery/node-twitter-api-v2/discussions/459).
+
+## Highlights
+
+✅ **Ready for v2 and good ol' v1.1 Twitter API**
+
+✅ **Light: No dependencies, 23kb minified+gzipped**
+
+✅ **Bundled types for request parameters and responses**
+
+✅ **Streaming support**
+
+✅ **Pagination utils**
+
+✅ **User-context authentication with OAuth2**
+
+✅ **Media upload helpers**
+
+## How to use
+
+Install it through your favorite package manager:
+```bash
+yarn add twitter-api-v2
+# or
+npm i twitter-api-v2
+```
+
+Here's a quick example of usage:
+
+```ts
+import { TwitterApi } from 'twitter-api-v2';
+
+// Instantiate with desired auth type (here's Bearer v2 auth)
+const twitterClient = new TwitterApi('');
+
+// Tell typescript it's a readonly app
+const readOnlyClient = twitterClient.readOnly;
+
+// Play with the built in methods
+const user = await readOnlyClient.v2.userByUsername('plhery');
+await twitterClient.v2.tweet('Hello, this is a test.');
+// You can upload media easily!
+await twitterClient.v1.uploadMedia('./big-buck-bunny.mp4');
+```
+
+## Why?
+
+Sometimes, you just want to quickly bootstrap an application using the Twitter API.
+Even though there are a lot of libraries available on the JavaScript ecosystem, they usually just
+provide wrappers around HTTP methods, and some of them are bloated with many dependencies.
+
+`twitter-api-v2` is meant to provide full endpoint wrapping, from method name to response data,
+using descriptive typings for read/write/DMs rights, request parameters and response payload.
+
+A small feature comparison with other libs:
+
+| Package | API version(s) | Response typings | Media helpers | Pagination | Subdeps | Size (gzip) | Install size |
+| -------------- | -------------- | ---------------- | ------------- | ---------- | --------------- | -------------:| -------------:|
+| twitter-api-v2 | v1.1, v2, labs | ✅ | ✅ | ✅ | 0 | ~23 kB | [](https://packagephobia.com/result?p=twitter-api-v2) |
+| twit | v1.1 | ❌ | ✅ | ❌ | 51 | ~214.5 kB | [](https://packagephobia.com/result?p=twit) |
+| twitter | v1.1 | ❌ | ❌ | ❌ | 50 | ~182.1 kB | [](https://packagephobia.com/result?p=twitter) |
+| twitter-lite | v1.1, v2 | ❌ | ❌ | ❌ | 4 | ~5.3 kB | [](https://packagephobia.com/result?p=twitter-lite) |
+| twitter-v2 | v2 | ❌ | ❌ | ❌ | 7 | ~4.5 kB | [](https://packagephobia.com/result?p=twitter-v2) |
+
+## Features
+
+Here's everything `twitter-api-v2` can do:
+
+### Basics:
+- Support for v1.1 and **v2 of Twitter API**
+- Make signed HTTP requests to Twitter with every auth type: **OAuth 1.0a**, **OAuth2** (even brand new user context OAuth2!) and **Basic** HTTP Authorization
+- Helpers for numerous HTTP request methods (`GET`, `POST`, `PUT`, `DELETE` and `PATCH`),
+ that handle query string parse & format, automatic body formatting and more
+- High-class support for stream endpoints, with easy data consumption and auto-reconnect on stream errors
+
+### Request helpers:
+- Automatic paginator for endpoints like user and tweet timelines,
+ allowing payload consumption with modern asynchronous iterators until your rate-limit is hit
+- Convenient methods for authentication - generate auth links and ask for tokens to your users
+- Media upload with API v1.1, including **long video & subtitles support**, automatic media type detection,
+ **chunked upload** and support for **concurrent uploads**
+- Dedicated methods that wraps API v1.1 & v2 endpoints, with **typed arguments** and fully **typed responses**
+- Typed errors, meaningful error messages, error enumerations for both v1.1 and v2
+
+### Type-safe first:
+- **Typings for tweet, user, media entities (and more) are bundled!**
+- Type-safe wrapping of dedicated methods in 3 right level: *DM*/*Read-write*/*Read-only* (just like Twitter API do!) -
+ you can declare a read-only client - you will only see the methods associated with read-only endpoints
+
+And last but not least, fully powered by native `Promise`s.
+
+## Documentation
+
+Learn how to use the full potential of `twitter-api-v2`.
+
+- Get started
+ - [Create a client and make your first request](./doc/basics.md)
+ - [Handle Twitter authentication flows](./doc/auth.md)
+ - [Explore some examples](./doc/examples.md)
+ - [Use and create plugins](./doc/plugins.md)
+- Use endpoints wrappers — ensure typings of request & response
+ - [Available endpoint wrappers for v1.1 API](./doc/v1.md)
+ - [Available endpoint wrappers for v2 API](./doc/v2.md)
+ - [Use Twitter streaming endpoints (v1.1 & v2)](./doc/streaming.md)
+- Deep diving into requests
+ - [Use direct HTTP-method wrappers](./doc/http-wrappers.md)
+ - [Use rate limit helpers](./doc/rate-limiting.md)
+ - [Handle errors](./doc/errors.md)
+ - [Master `twitter-api-v2` paginators](./doc/paginators.md)
+ - [Discover available helpers](./doc/helpers.md)
+
+## Plugins
+
+Official plugins for `twitter-api-v2`:
+- [`@twitter-api-v2/plugin-token-refresher`](https://www.npmjs.com/package/@twitter-api-v2/plugin-token-refresher): Handle OAuth 2.0 (user-context) token refreshing for you
+- [`@twitter-api-v2/plugin-rate-limit`](https://www.npmjs.com/package/@twitter-api-v2/plugin-rate-limit): Access and store automatically rate limit data
+- [`@twitter-api-v2/plugin-cache-redis`](https://www.npmjs.com/package/@twitter-api-v2/plugin-cache-redis): Store responses in a Redis store and serve cached responses
+
+See [how to use plugins here](./doc/plugins.md).
diff --git a/node_modules/twitter-api-v2/changelog.md b/node_modules/twitter-api-v2/changelog.md
new file mode 100644
index 0000000..e9c2156
--- /dev/null
+++ b/node_modules/twitter-api-v2/changelog.md
@@ -0,0 +1,306 @@
+1.15.1
+------
+- fix: Update tweet.definition.v2.ts to add public view count #494 (@sebastianspiegel)
+- chore: Update documentation #486 (@ry0y4n)
+
+1.15.0
+------
+- fix: Add missing client settings when fetching the token #480 (@qfish)
+
+1.14.3
+------
+- fix: support mov video type #478 (@wass08)
+
+1.14.2
+------
+- feat: add subscriber_count to spaces typings #452 (@florrdv)
+- chore: Fix typo #454 (@will2022)
+
+1.14.1
+------
+- feat: add verified_type to user schema #442 (@dkulyk)
+- chore: fix typos and markdown links #443 (@Jiralite)
+
+1.14.0
+------
+- feat: improve search query params #431 (@itsjustbrian)
+- breaking change: DM Ids should be strings #436
+
+1.13.0
+------
+- feat: Add DM events endpoints
+- feat: Add space tweet endpoint
+
+1.12.10
+-------
+- fix: Typing issue in v1 DM medias - ReceivedMessageCreateDataV1 #407 (@secchanu)
+- fix: Allow overriding the content-type header #413 (@alessandrovisentini)
+- fix: readme typo #414 (@vrrdnt)
+
+1.12.9
+------
+- Fix: Add missing expansions/'tweet.fields' item for tweet edition #392
+- friends/followers objects list V1 #391 (@Abdullah-Malik)
+
+1.12.8
+------
+- Feat: Add `edit_history_tweet_ids` to `TweetV2`
+- Feat: Add v1 friends/followers paginators (thanks to @Abdullah-Malik) #380
+
+1.12.7
+------
+- Fix: Fix Exception throw when response data is truthy but not an object (for example, a raw HTML page) #354
+- Fix: Typing issue with `TwitterApiErrorData.errors` that can be `undefined` in some cases #357
+- Feat: Add `include_rts` parameters for `.userTimeline` #349
+
+1.12.6
+------
+- Feat: add follow and unfollow api V1 methods (thanks to @Abdullah-Malik)
+
+1.12.5
+------
+- Fix: Better check for error presence in `ApiResponseError` instantiation
+
+1.12.4
+------
+- Fix: Ignore rate limit data for endpoints without rate limit headers in paginators #341
+- Fix: Patch for unifiying endpoints with various error payload in v1 API #342
+- Feat: `variants` property for `media.fields`, add `MediaVariantsV2` interface (thanks to @roncli) #347
+
+1.12.3
+------
+- Feat: .favoriteTimeline for API v1 #296 (thanks to @AuroraDysis)
+- Feat: duration_millis property for v1 medias (thanks to @RyoshiKayo)
+- Feat: source_user_id and source_user_id_str missing properties in MediaEntityV1 (thanks to @AuroraDysis)
+
+1.12.2
+------
+- Feat: .homeTimeline for API v2 #288
+
+1.12.1
+------
+- Fix: missing id prop of TweetEntityMentionV2 #274 (@lima-eduardo)
+- Fix: add place_id to SendTweetV1Params #287 (@viniciuskneves)
+
+1.12.0
+------
+- Feat: Update plugin API to support response overloading on error #248
+- Feat: `.quote` method to create a retweet with comment (quoted tweet) in `v1` and `v2` #260 (@jonah-saltzman)
+
+1.11.3
+------
+- Feat: New spaces features: `topic_ids` and `ended_at` on space object, `/spaces/:id/buyers` endpoint #237
+- Feat: New bookmarks API #237
+- Feat: New Quoted tweets endpoint #237
+- Feat: Allow v2.search to be used without query parameter #252
+- Fix: Usertimeline v1 endpoint .done property value is false #238
+- Feat: `sort_order` parameter #246 (@nolbuzanis)
+- Fix: Better error message for failed media uploads #244 (@nolbuzanis)
+
+1.11.2
+------
+- Fix: .meta is not correctly typed in paginators #231
+- Fix: Caught promise is rejected without ability of catching it later when a request fails and a plugin is used #229
+
+1.11.1
+------
+- Feat: Support error hooks in plugins #226 #227
+- Fix: Bypass Twitter v2 incoherence by converting `start_time` to a valid `since_id` when `until_id` is used in paginators #197 #228
+- Feat: Getter for DM images `.v1.downloadDmImage` to download images hosted on `ton.twitter.com` protected by OAuth 1.0a
+
+1.11.0
+------
+- Feat: Support plugins (more features coming soon as plugins!)
+- Feat: Compression level can now be specified explicitly
+- Refactor: `.v1.uploadMedia()` now accept `options.mimeType` and `options.longVideo` as argument, in replacement of `options.type` (which is now deprecated)
+- Fix: OAuth2 scope incorrectly encoded #184
+
+1.10.3
+------
+- Feat: Native support of gzip compression for streaming endpoints
+- Feat: Native support of brotli (25% more compressed than gzip) compression for non-streaming endpoints, when available
+
+1.10.2
+------
+- Feat: Native support of gzip/deflate compression for non-streaming endpoints
+
+1.10.1
+------
+- Fix: Crash when a v2 paginator is empty and response does not contains a `.meta` property #177
+- Fix: "Memory leak" when response are abruptly closed by Twitter or OS, because no close/error listener on response object was attributed
+
+1.10.0
+------
+- Feat: Pagination support for `tweets/:id/liking_users` and `tweets/:id/retweeted_by` #165
+- Feat: Support custom Node HTTP agents #149
+- Doc: Better example for `.v2.me()` and fix typos #160 #164 (thanks to @rbochenek and @ShubhamKushwah)
+
+1.9.1
+-----
+- Fix: Use next_token instead of until_id if pagination token available #152
+
+1.9.0
+-----
+- Feat: Helpers for v2 includes
+- Feat: Support for custom debug loggers
+- Fix: Errors accessor to get API errors in paginators #145
+- Fix: Correctly update .includes/.meta/.errors in paginators when using async iterator #142
+- Fix: Incorrect HTTP method for GET lists #147 #148
+- Doc: Better doc & examples for OAuth 2.0 user-context
+
+1.8.1
+-----
+- Feat: Add every GET lists v2 endpoints
+
+1.8.0
+-----
+- Feat: Add OAuth2 user-context support
+- Feat: Add users/me v2 endpoint wrapper
+
+1.7.2
+-----
+- Fix: Paginator can return multiple times the same results in some conditions
+- Feat: .done property for paginators, to know when a next page is fetchable
+
+1.7.1
+-----
+- Fix: wrong type for optional parameter images in TweetEntityUrlV2
+
+1.7.0
+-----
+- Feat: Create tweet v2 endpoint (thanks to @sudo-kaizen) #110
+- Feat: Delete tweet v2 endpoint (thanks to @sudo-kaizen) #111
+- Feat: Tweet thread and reply to a tweet v2
+- Fix: BREAKING: Explicitly specify userId on userMutingUsers (thanks to @mika-f) #114
+
+1.6.5
+-----
+- Fix: Increase retry timeout on stream reconnection
+
+1.6.4
+-----
+- Fix: Reject stream reconnection if a reconnect process is already started
+
+1.6.3
+-----
+- Fix: Streams will know correctly reject `.connect` `Promise` on connection error if `autoReconnect` is `false`
+
+1.6.2
+-----
+- Feat: Streams do now support auto-reconnection for the initial connection attempt
+
+1.6.1
+-----
+- Feat: New option for creating streams, `autoConnect` that is `true` by default ; Setting the value to `false` will cause the `TweetStream` object to be returned immediately (not in a `Promise`), because connection isn't awaited #92
+- Fix: `autoReconnectRetries`: Setting this params to `Infinity` no longer causes the stream reconnection attempts to be delayed to next event loop turn #92
+- Fix: Use `https.request(options)` instead of `https.request(url, options)`, because some people has outdated dependencies that overwrite native Node's exported function and break its signature #94 #96
+- Feat: Next retry timeout computation can be customized by using `.nextRetryTimeout` property of `TweetStream` instance, that is function taking a `tryOccurrence` and returning the number of milliseconds to wait before trying to reconnect
+
+1.6.0
+-----
+- Feat: List v2 muted users endpoint #89
+- Feat: Manage v2 lists endpoints
+- Feat: Support user-flow with OAuth2 (beta - not documented yet)
+- Fix: Incorrect typing for createMediaMetadata #93
+
+1.5.2
+-----
+- Feat: Tweet thread helper #76 #79
+- Fix: Explicit max_results parameters should now work properly in paginators #74 #84
+- Fix: Endpoints with parameterized URLs now registers properly rate-limit data in cache store
+
+1.5.1
+-----
+- Fix: Fix return type for v1.1 'tweets' wrapper #72
+
+1.5.0
+-----
+- Feat: v1.1 List endpoints, GET and POST, with doc, paginators and typings #70
+- Feat: Save rate limit information for last request of each endpoint #70
+- Doc: Documentation improvements for uploading media #68 #70
+- Doc: Fixed parameter name #67
+
+1.4.1
+-----
+- Fix: Incorrect type union in MessageCreateAttachmentV1 & MessageCreateLocationV1
+- Doc: Added real-life examples
+- Doc: Add Twitter doc link to .tweet/.reply
+
+1.4.0
+-----
+- Feat: Add every oauth/authenticate parameters #54 - thanks to @tbhmens
+- Fix: Set allowSyntheticDefaultImport to false to improve compat #57 - thanks to @PLHery
+- Feat: Add missing tweet.field items in type enumeration #60 - thanks to @filippkowalski
+- Doc: Add info about error handling #61
+- Feat: Endpoint wrappers for v2 Spaces endpoints #62
+- Feat: Endpoint wrappers for v2 Batch Compliance endpoints #62
+- Feat: Types & wrappers for account, friendships, users and tweets v1.1 endpoints #64
+- Fix: Incorrect encoding of '*' character in query strings #63 #64
+
+1.3.0
+-----
+- Doc: Improve rate-limit documentation #47 #32
+- Feat: Public Direct Messages (DMs) 1.1 endpoints support: wrappers, typings, docs and tests #48
+- Feat: New 05/06/07-2021 v2 endpoints wrappers #50
+- Feat: Paginator mode for .following/.followers for v2 #50
+- Fix: Many fixes for tweet streams auto-reconnect, handle connection errors more smoothly #50
+- Feat: New events for tweet streams, that includes lost connection and reconnections #50
+- Feat: Handle stream errors deliveries in a dedicated .DataError event (for v2 tweet streams) #50
+- Fix: Corrections for body-mode auto-detection (mainly for manual API requests) #53
+
+1.2.0
+-----
+- Fix: fetchLast was throwing an error with timelines #43
+- Feat: Add .meta and .includes in v2 paginators #35 #46
+- Feat: Add some missing attributes to tweetEntity typings #42
+
+1.1.1
+-----
+- Fix: in streams, the KeepAlive was not emitted #33
+
+1.1.0
+-----
+- Add the new v2 likes endpoint
+- Fix: add some missing media types
+
+1.0.0
+-----
+First Stable Version
+- More tests, way more documentation
+- Add every missing v2 endpoints
+- Remove the two dependencies (form-data and oauth)
+- Improve error management
+- Fix issues with node12
+- Fix issues with the auth API
+
+0.4.0
+-----
+- Add V1 and V2 streaming V2 endpoints
+- Add V2 followers and following endpoints
+- Refactor / various fixes
+
+0.3.0
+-----
+- Add the four API v2 user endpoints
+- Improve type definitions
+- Minor v2 search refactor
+
+0.2.3
+-----
+- Fix npm package (was not built)
+
+0.2.1
+-----
+- Export typescript definitions
+
+0.2.0
+-----
+- Link and Oauth auth
+- PUT/PATCH/DELETE
+- improve get/post methods (build query strings, v1/v2 urls, ...)
+- read/write/DMs segmentation
+- native media chunked upload, with simultaneous send of file parts
+
+0.1.0
+-----
+- First foundations
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.d.ts
new file mode 100644
index 0000000..78af26c
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.d.ts
@@ -0,0 +1,24 @@
+///
+declare type TStringable = {
+ toString(): string;
+};
+export declare class FormDataHelper {
+ protected _boundary: string;
+ protected _chunks: Buffer[];
+ protected _footerChunk?: Buffer;
+ protected static readonly LINE_BREAK = "\r\n";
+ protected static readonly DEFAULT_CONTENT_TYPE = "application/octet-stream";
+ protected bodyAppend(...values: (Buffer | string)[]): void;
+ append(field: string, value: Buffer | string | TStringable, contentType?: string): void;
+ getHeaders(): {
+ 'content-type': string;
+ };
+ /** Length of form-data (including footer length). */
+ protected getLength(): number;
+ getBuffer(): Buffer;
+ protected getBoundary(): string;
+ protected generateBoundary(): void;
+ protected getMultipartHeader(field: string, value: string | Buffer, contentType?: string): string;
+ protected getMultipartFooter(): Buffer;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.js
new file mode 100644
index 0000000..6a035b3
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/form-data.helper.js
@@ -0,0 +1,83 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.FormDataHelper = void 0;
+const helpers_1 = require("../helpers");
+// This class is partially inspired by https://github.com/form-data/form-data/blob/master/lib/form_data.js
+// All credits to their authors.
+class FormDataHelper {
+ constructor() {
+ this._boundary = '';
+ this._chunks = [];
+ }
+ bodyAppend(...values) {
+ const allAsBuffer = values.map(val => val instanceof Buffer ? val : Buffer.from(val));
+ this._chunks.push(...allAsBuffer);
+ }
+ append(field, value, contentType) {
+ const convertedValue = value instanceof Buffer ? value : value.toString();
+ const header = this.getMultipartHeader(field, convertedValue, contentType);
+ this.bodyAppend(header, convertedValue, FormDataHelper.LINE_BREAK);
+ }
+ getHeaders() {
+ return {
+ 'content-type': 'multipart/form-data; boundary=' + this.getBoundary(),
+ };
+ }
+ /** Length of form-data (including footer length). */
+ getLength() {
+ return this._chunks.reduce((acc, cur) => acc + cur.length, this.getMultipartFooter().length);
+ }
+ getBuffer() {
+ const allChunks = [...this._chunks, this.getMultipartFooter()];
+ const totalBuffer = Buffer.alloc(this.getLength());
+ let i = 0;
+ for (const chunk of allChunks) {
+ for (let j = 0; j < chunk.length; i++, j++) {
+ totalBuffer[i] = chunk[j];
+ }
+ }
+ return totalBuffer;
+ }
+ getBoundary() {
+ if (!this._boundary) {
+ this.generateBoundary();
+ }
+ return this._boundary;
+ }
+ generateBoundary() {
+ // This generates a 50 character boundary similar to those used by Firefox.
+ let boundary = '--------------------------';
+ for (let i = 0; i < 24; i++) {
+ boundary += Math.floor(Math.random() * 10).toString(16);
+ }
+ this._boundary = boundary;
+ }
+ getMultipartHeader(field, value, contentType) {
+ // In this lib no need to guess more the content type, octet stream is ok of buffers
+ if (!contentType) {
+ contentType = value instanceof Buffer ? FormDataHelper.DEFAULT_CONTENT_TYPE : '';
+ }
+ const headers = {
+ 'Content-Disposition': ['form-data', `name="${field}"`],
+ 'Content-Type': contentType,
+ };
+ let contents = '';
+ for (const [prop, header] of Object.entries(headers)) {
+ // skip nullish headers.
+ if (!header.length) {
+ continue;
+ }
+ contents += prop + ': ' + (0, helpers_1.arrayWrap)(header).join('; ') + FormDataHelper.LINE_BREAK;
+ }
+ return '--' + this.getBoundary() + FormDataHelper.LINE_BREAK + contents + FormDataHelper.LINE_BREAK;
+ }
+ getMultipartFooter() {
+ if (this._footerChunk) {
+ return this._footerChunk;
+ }
+ return this._footerChunk = Buffer.from('--' + this.getBoundary() + '--' + FormDataHelper.LINE_BREAK);
+ }
+}
+exports.FormDataHelper = FormDataHelper;
+FormDataHelper.LINE_BREAK = '\r\n';
+FormDataHelper.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.d.ts
new file mode 100644
index 0000000..b897933
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.d.ts
@@ -0,0 +1,40 @@
+export interface OAuth1Tokens {
+ key: string;
+ secret: string;
+}
+export interface OAuth1MakerArgs {
+ consumerKeys: OAuth1Tokens;
+}
+export interface OAuth1RequestOptions {
+ url: string;
+ method: string;
+ data?: any;
+}
+export interface OAuth1AuthInfo {
+ oauth_consumer_key: string;
+ oauth_nonce: string;
+ oauth_signature_method: string;
+ oauth_timestamp: number;
+ oauth_version: string;
+ oauth_token: string;
+ oauth_signature: string;
+}
+export declare class OAuth1Helper {
+ nonceLength: number;
+ protected consumerKeys: OAuth1Tokens;
+ constructor(options: OAuth1MakerArgs);
+ static percentEncode(str: string): string;
+ protected hash(base: string, key: string): string;
+ authorize(request: OAuth1RequestOptions, accessTokens?: Partial): OAuth1AuthInfo;
+ toHeader(oauthInfo: OAuth1AuthInfo): {
+ Authorization: string;
+ };
+ protected getNonce(): string;
+ protected getTimestamp(): number;
+ protected getSignature(request: OAuth1RequestOptions, tokenSecret: string | undefined, oauthInfo: OAuth1AuthInfo): string;
+ protected getSigningKey(tokenSecret: string | undefined): string;
+ protected getBaseString(request: OAuth1RequestOptions, oauthInfo: OAuth1AuthInfo): string;
+ protected getParameterString(request: OAuth1RequestOptions, oauthInfo: OAuth1AuthInfo): string;
+ protected getBaseUrl(url: string): string;
+}
+export default OAuth1Helper;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.js
new file mode 100644
index 0000000..dac80d3
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth1.helper.js
@@ -0,0 +1,187 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OAuth1Helper = void 0;
+const crypto = __importStar(require("crypto"));
+class OAuth1Helper {
+ constructor(options) {
+ this.nonceLength = 32;
+ this.consumerKeys = options.consumerKeys;
+ }
+ static percentEncode(str) {
+ return encodeURIComponent(str)
+ .replace(/!/g, '%21')
+ .replace(/\*/g, '%2A')
+ .replace(/'/g, '%27')
+ .replace(/\(/g, '%28')
+ .replace(/\)/g, '%29');
+ }
+ hash(base, key) {
+ return crypto
+ .createHmac('sha1', key)
+ .update(base)
+ .digest('base64');
+ }
+ authorize(request, accessTokens = {}) {
+ const oauthInfo = {
+ oauth_consumer_key: this.consumerKeys.key,
+ oauth_nonce: this.getNonce(),
+ oauth_signature_method: 'HMAC-SHA1',
+ oauth_timestamp: this.getTimestamp(),
+ oauth_version: '1.0',
+ };
+ if (accessTokens.key !== undefined) {
+ oauthInfo.oauth_token = accessTokens.key;
+ }
+ if (!request.data) {
+ request.data = {};
+ }
+ oauthInfo.oauth_signature = this.getSignature(request, accessTokens.secret, oauthInfo);
+ return oauthInfo;
+ }
+ toHeader(oauthInfo) {
+ const sorted = sortObject(oauthInfo);
+ let header_value = 'OAuth ';
+ for (const element of sorted) {
+ if (element.key.indexOf('oauth_') !== 0) {
+ continue;
+ }
+ header_value += OAuth1Helper.percentEncode(element.key) + '="' + OAuth1Helper.percentEncode(element.value) + '",';
+ }
+ return {
+ // Remove the last ,
+ Authorization: header_value.slice(0, header_value.length - 1),
+ };
+ }
+ getNonce() {
+ const wordCharacters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ let result = '';
+ for (let i = 0; i < this.nonceLength; i++) {
+ result += wordCharacters[Math.trunc(Math.random() * wordCharacters.length)];
+ }
+ return result;
+ }
+ getTimestamp() {
+ return Math.trunc(new Date().getTime() / 1000);
+ }
+ getSignature(request, tokenSecret, oauthInfo) {
+ return this.hash(this.getBaseString(request, oauthInfo), this.getSigningKey(tokenSecret));
+ }
+ getSigningKey(tokenSecret) {
+ return OAuth1Helper.percentEncode(this.consumerKeys.secret) + '&' + OAuth1Helper.percentEncode(tokenSecret || '');
+ }
+ getBaseString(request, oauthInfo) {
+ return request.method.toUpperCase() + '&'
+ + OAuth1Helper.percentEncode(this.getBaseUrl(request.url)) + '&'
+ + OAuth1Helper.percentEncode(this.getParameterString(request, oauthInfo));
+ }
+ getParameterString(request, oauthInfo) {
+ const baseStringData = sortObject(percentEncodeData(mergeObject(oauthInfo, mergeObject(request.data, deParamUrl(request.url)))));
+ let dataStr = '';
+ for (const { key, value } of baseStringData) {
+ // check if the value is an array
+ // this means that this key has multiple values
+ if (value && Array.isArray(value)) {
+ // sort the array first
+ value.sort();
+ let valString = '';
+ // serialize all values for this key: e.g. formkey=formvalue1&formkey=formvalue2
+ value.forEach((item, i) => {
+ valString += key + '=' + item;
+ if (i < value.length) {
+ valString += '&';
+ }
+ });
+ dataStr += valString;
+ }
+ else {
+ dataStr += key + '=' + value + '&';
+ }
+ }
+ // Remove the last character
+ return dataStr.slice(0, dataStr.length - 1);
+ }
+ getBaseUrl(url) {
+ return url.split('?')[0];
+ }
+}
+exports.OAuth1Helper = OAuth1Helper;
+exports.default = OAuth1Helper;
+// Helper functions //
+function mergeObject(obj1, obj2) {
+ return {
+ ...obj1 || {},
+ ...obj2 || {},
+ };
+}
+function sortObject(data) {
+ return Object.keys(data)
+ .sort()
+ .map(key => ({ key, value: data[key] }));
+}
+function deParam(string) {
+ const split = string.split('&');
+ const data = {};
+ for (const coupleKeyValue of split) {
+ const [key, value = ''] = coupleKeyValue.split('=');
+ // check if the key already exists
+ // this can occur if the QS part of the url contains duplicate keys like this: ?formkey=formvalue1&formkey=formvalue2
+ if (data[key]) {
+ // the key exists already
+ if (!Array.isArray(data[key])) {
+ // replace the value with an array containing the already present value
+ data[key] = [data[key]];
+ }
+ // and add the new found value to it
+ data[key].push(decodeURIComponent(value));
+ }
+ else {
+ // it doesn't exist, just put the found value in the data object
+ data[key] = decodeURIComponent(value);
+ }
+ }
+ return data;
+}
+function deParamUrl(url) {
+ const tmp = url.split('?');
+ if (tmp.length === 1)
+ return {};
+ return deParam(tmp[1]);
+}
+function percentEncodeData(data) {
+ const result = {};
+ for (const key in data) {
+ let value = data[key];
+ // check if the value is an array
+ if (value && Array.isArray(value)) {
+ value = value.map(v => OAuth1Helper.percentEncode(v));
+ }
+ else {
+ value = OAuth1Helper.percentEncode(value);
+ }
+ result[OAuth1Helper.percentEncode(key)] = value;
+ }
+ return result;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.d.ts
new file mode 100644
index 0000000..7b8c886
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.d.ts
@@ -0,0 +1,7 @@
+export declare class OAuth2Helper {
+ static getCodeVerifier(): string;
+ static getCodeChallengeFromVerifier(verifier: string): string;
+ static getAuthHeader(clientId: string, clientSecret: string): string;
+ static generateRandomString(length: number): string;
+ private static escapeBase64Url;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.js
new file mode 100644
index 0000000..3e41410
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/oauth2.helper.js
@@ -0,0 +1,54 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OAuth2Helper = void 0;
+const crypto = __importStar(require("crypto"));
+class OAuth2Helper {
+ static getCodeVerifier() {
+ return this.generateRandomString(128);
+ }
+ static getCodeChallengeFromVerifier(verifier) {
+ return this.escapeBase64Url(crypto
+ .createHash('sha256')
+ .update(verifier)
+ .digest('base64'));
+ }
+ static getAuthHeader(clientId, clientSecret) {
+ const key = encodeURIComponent(clientId) + ':' + encodeURIComponent(clientSecret);
+ return Buffer.from(key).toString('base64');
+ }
+ static generateRandomString(length) {
+ let text = '';
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
+ for (let i = 0; i < length; i++) {
+ text += possible[Math.floor(Math.random() * possible.length)];
+ }
+ return text;
+ }
+ static escapeBase64Url(string) {
+ return string.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
+ }
+}
+exports.OAuth2Helper = OAuth2Helper;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.d.ts
new file mode 100644
index 0000000..34c76f6
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.d.ts
@@ -0,0 +1,64 @@
+///
+///
+///
+///
+///
+import type { Socket } from 'net';
+import type { IncomingMessage, ClientRequest } from 'http';
+import TweetStream from '../stream/TweetStream';
+import { ApiPartialResponseError, ApiRequestError, ApiResponseError } from '../types';
+import type { ErrorV1, ErrorV2, TwitterRateLimit, TwitterResponse } from '../types';
+import type { TRequestFullData, TRequestFullStreamData, TResponseParseMode } from '../types/request-maker.mixin.types';
+import * as zlib from 'zlib';
+import { Readable } from 'stream';
+declare type TRequestReadyPayload = {
+ req: ClientRequest;
+ res: Readable;
+ originalResponse: IncomingMessage;
+ requestData: TRequestFullData | TRequestFullStreamData;
+};
+declare type TReadyRequestResolver = (value: TRequestReadyPayload) => void;
+declare type TResponseResolver = (value: TwitterResponse) => void;
+declare type TRequestRejecter = (error: ApiRequestError) => void;
+declare type TResponseRejecter = (error: ApiResponseError | ApiPartialResponseError) => void;
+interface IBuildErrorParams {
+ res: IncomingMessage;
+ data: any;
+ rateLimit?: TwitterRateLimit;
+ code: number;
+}
+export declare class RequestHandlerHelper {
+ protected requestData: TRequestFullData | TRequestFullStreamData;
+ protected req: ClientRequest;
+ protected res: IncomingMessage;
+ protected requestErrorHandled: boolean;
+ protected responseData: Buffer[];
+ constructor(requestData: TRequestFullData | TRequestFullStreamData);
+ get hrefPathname(): string;
+ protected isCompressionDisabled(): boolean;
+ protected isFormEncodedEndpoint(): boolean;
+ protected createRequestError(error: Error): ApiRequestError;
+ protected createPartialResponseError(error: Error, abortClose: boolean): ApiPartialResponseError;
+ protected formatV1Errors(errors: ErrorV1[]): string;
+ protected formatV2Error(error: ErrorV2): string;
+ protected createResponseError({ res, data, rateLimit, code }: IBuildErrorParams): ApiResponseError;
+ protected getResponseDataStream(res: IncomingMessage): IncomingMessage | zlib.BrotliDecompress;
+ protected detectResponseType(res: IncomingMessage): TResponseParseMode;
+ protected getParsedResponse(res: IncomingMessage): any;
+ protected getRateLimitFromResponse(res: IncomingMessage): TwitterRateLimit | undefined;
+ protected onSocketEventHandler(reject: TRequestRejecter, socket: Socket): void;
+ protected onSocketCloseHandler(reject: TRequestRejecter): void;
+ protected requestErrorHandler(reject: TRequestRejecter, requestError: Error): void;
+ protected timeoutErrorHandler(): void;
+ protected classicResponseHandler(resolve: TResponseResolver, reject: TResponseRejecter, res: IncomingMessage): void;
+ protected onResponseEndHandler(resolve: TResponseResolver, reject: TResponseRejecter): void;
+ protected onResponseCloseHandler(resolve: TResponseResolver, reject: TResponseRejecter): void;
+ protected streamResponseHandler(resolve: TReadyRequestResolver, reject: TResponseRejecter, res: IncomingMessage): void;
+ protected debugRequest(): void;
+ protected buildRequest(): void;
+ protected registerRequestEventDebugHandlers(req: ClientRequest): void;
+ makeRequest(): Promise>;
+ makeRequestAsStream(): Promise>;
+ makeRequestAndResolveWhenReady(): Promise;
+}
+export default RequestHandlerHelper;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.js
new file mode 100644
index 0000000..0a546e3
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-handler.helper.js
@@ -0,0 +1,391 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RequestHandlerHelper = void 0;
+const https_1 = require("https");
+const settings_1 = require("../settings");
+const TweetStream_1 = __importDefault(require("../stream/TweetStream"));
+const types_1 = require("../types");
+const zlib = __importStar(require("zlib"));
+class RequestHandlerHelper {
+ constructor(requestData) {
+ this.requestData = requestData;
+ this.requestErrorHandled = false;
+ this.responseData = [];
+ }
+ /* Request helpers */
+ get hrefPathname() {
+ const url = this.requestData.url;
+ return url.hostname + url.pathname;
+ }
+ isCompressionDisabled() {
+ return !this.requestData.compression || this.requestData.compression === 'identity';
+ }
+ isFormEncodedEndpoint() {
+ return this.requestData.url.href.startsWith('https://api.twitter.com/oauth/');
+ }
+ /* Error helpers */
+ createRequestError(error) {
+ if (settings_1.TwitterApiV2Settings.debug) {
+ settings_1.TwitterApiV2Settings.logger.log('Request error:', error);
+ }
+ return new types_1.ApiRequestError('Request failed.', {
+ request: this.req,
+ error,
+ });
+ }
+ createPartialResponseError(error, abortClose) {
+ const res = this.res;
+ let message = `Request failed with partial response with HTTP code ${res.statusCode}`;
+ if (abortClose) {
+ message += ' (connection abruptly closed)';
+ }
+ else {
+ message += ' (parse error)';
+ }
+ return new types_1.ApiPartialResponseError(message, {
+ request: this.req,
+ response: this.res,
+ responseError: error,
+ rawContent: Buffer.concat(this.responseData).toString(),
+ });
+ }
+ formatV1Errors(errors) {
+ return errors
+ .map(({ code, message }) => `${message} (Twitter code ${code})`)
+ .join(', ');
+ }
+ formatV2Error(error) {
+ return `${error.title}: ${error.detail} (see ${error.type})`;
+ }
+ createResponseError({ res, data, rateLimit, code }) {
+ var _a;
+ if (settings_1.TwitterApiV2Settings.debug) {
+ settings_1.TwitterApiV2Settings.logger.log(`Request failed with code ${code}, data:`, data);
+ settings_1.TwitterApiV2Settings.logger.log('Response headers:', res.headers);
+ }
+ // Errors formatting.
+ let errorString = `Request failed with code ${code}`;
+ if ((_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a.length) {
+ const errors = data.errors;
+ if ('code' in errors[0]) {
+ errorString += ' - ' + this.formatV1Errors(errors);
+ }
+ else {
+ errorString += ' - ' + this.formatV2Error(data);
+ }
+ }
+ return new types_1.ApiResponseError(errorString, {
+ code,
+ data,
+ headers: res.headers,
+ request: this.req,
+ response: res,
+ rateLimit,
+ });
+ }
+ /* Response helpers */
+ getResponseDataStream(res) {
+ if (this.isCompressionDisabled()) {
+ return res;
+ }
+ const contentEncoding = (res.headers['content-encoding'] || 'identity').trim().toLowerCase();
+ if (contentEncoding === 'br') {
+ const brotli = zlib.createBrotliDecompress({
+ flush: zlib.constants.BROTLI_OPERATION_FLUSH,
+ finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH,
+ });
+ res.pipe(brotli);
+ return brotli;
+ }
+ if (contentEncoding === 'gzip') {
+ const gunzip = zlib.createGunzip({
+ flush: zlib.constants.Z_SYNC_FLUSH,
+ finishFlush: zlib.constants.Z_SYNC_FLUSH,
+ });
+ res.pipe(gunzip);
+ return gunzip;
+ }
+ if (contentEncoding === 'deflate') {
+ const inflate = zlib.createInflate({
+ flush: zlib.constants.Z_SYNC_FLUSH,
+ finishFlush: zlib.constants.Z_SYNC_FLUSH,
+ });
+ res.pipe(inflate);
+ return inflate;
+ }
+ return res;
+ }
+ detectResponseType(res) {
+ var _a, _b;
+ // Auto parse if server responds with JSON body
+ if (((_a = res.headers['content-type']) === null || _a === void 0 ? void 0 : _a.includes('application/json')) || ((_b = res.headers['content-type']) === null || _b === void 0 ? void 0 : _b.includes('application/problem+json'))) {
+ return 'json';
+ }
+ // f-e oauth token endpoints
+ else if (this.isFormEncodedEndpoint()) {
+ return 'url';
+ }
+ return 'text';
+ }
+ getParsedResponse(res) {
+ const data = this.responseData;
+ const mode = this.requestData.forceParseMode || this.detectResponseType(res);
+ if (mode === 'buffer') {
+ return Buffer.concat(data);
+ }
+ else if (mode === 'text') {
+ return Buffer.concat(data).toString();
+ }
+ else if (mode === 'json') {
+ const asText = Buffer.concat(data).toString();
+ return asText.length ? JSON.parse(asText) : undefined;
+ }
+ else if (mode === 'url') {
+ const asText = Buffer.concat(data).toString();
+ const formEntries = {};
+ for (const [item, value] of new URLSearchParams(asText)) {
+ formEntries[item] = value;
+ }
+ return formEntries;
+ }
+ else {
+ // mode === 'none'
+ return undefined;
+ }
+ }
+ getRateLimitFromResponse(res) {
+ let rateLimit = undefined;
+ if (res.headers['x-rate-limit-limit']) {
+ rateLimit = {
+ limit: Number(res.headers['x-rate-limit-limit']),
+ remaining: Number(res.headers['x-rate-limit-remaining']),
+ reset: Number(res.headers['x-rate-limit-reset']),
+ };
+ if (this.requestData.rateLimitSaver) {
+ this.requestData.rateLimitSaver(rateLimit);
+ }
+ }
+ return rateLimit;
+ }
+ /* Request event handlers */
+ onSocketEventHandler(reject, socket) {
+ socket.on('close', this.onSocketCloseHandler.bind(this, reject));
+ }
+ onSocketCloseHandler(reject) {
+ this.req.removeAllListeners('timeout');
+ const res = this.res;
+ if (res) {
+ // Response ok, res.close/res.end can handle request ending
+ return;
+ }
+ if (!this.requestErrorHandled) {
+ return reject(this.createRequestError(new Error('Socket closed without any information.')));
+ }
+ // else: other situation
+ }
+ requestErrorHandler(reject, requestError) {
+ var _a, _b;
+ (_b = (_a = this.requestData).requestEventDebugHandler) === null || _b === void 0 ? void 0 : _b.call(_a, 'request-error', { requestError });
+ this.requestErrorHandled = true;
+ reject(this.createRequestError(requestError));
+ }
+ timeoutErrorHandler() {
+ this.requestErrorHandled = true;
+ this.req.destroy(new Error('Request timeout.'));
+ }
+ /* Response event handlers */
+ classicResponseHandler(resolve, reject, res) {
+ this.res = res;
+ const dataStream = this.getResponseDataStream(res);
+ // Register the response data
+ dataStream.on('data', chunk => this.responseData.push(chunk));
+ dataStream.on('end', this.onResponseEndHandler.bind(this, resolve, reject));
+ dataStream.on('close', this.onResponseCloseHandler.bind(this, resolve, reject));
+ // Debug handlers
+ if (this.requestData.requestEventDebugHandler) {
+ this.requestData.requestEventDebugHandler('response', { res });
+ res.on('aborted', error => this.requestData.requestEventDebugHandler('response-aborted', { error }));
+ res.on('error', error => this.requestData.requestEventDebugHandler('response-error', { error }));
+ res.on('close', () => this.requestData.requestEventDebugHandler('response-close', { data: this.responseData }));
+ res.on('end', () => this.requestData.requestEventDebugHandler('response-end'));
+ }
+ }
+ onResponseEndHandler(resolve, reject) {
+ const rateLimit = this.getRateLimitFromResponse(this.res);
+ let data;
+ try {
+ data = this.getParsedResponse(this.res);
+ }
+ catch (e) {
+ reject(this.createPartialResponseError(e, false));
+ return;
+ }
+ // Handle bad error codes
+ const code = this.res.statusCode;
+ if (code >= 400) {
+ reject(this.createResponseError({ data, res: this.res, rateLimit, code }));
+ return;
+ }
+ if (settings_1.TwitterApiV2Settings.debug) {
+ settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${this.res.statusCode}`);
+ settings_1.TwitterApiV2Settings.logger.log('Response body:', data);
+ }
+ resolve({
+ data,
+ headers: this.res.headers,
+ rateLimit,
+ });
+ }
+ onResponseCloseHandler(resolve, reject) {
+ const res = this.res;
+ if (res.aborted) {
+ // Try to parse the request (?)
+ try {
+ this.getParsedResponse(this.res);
+ // Ok, try to resolve normally the request
+ return this.onResponseEndHandler(resolve, reject);
+ }
+ catch (e) {
+ // Parse error, just drop with content
+ return reject(this.createPartialResponseError(e, true));
+ }
+ }
+ if (!res.complete) {
+ return reject(this.createPartialResponseError(new Error('Response has been interrupted before response could be parsed.'), true));
+ }
+ // else: end has been called
+ }
+ streamResponseHandler(resolve, reject, res) {
+ const code = res.statusCode;
+ if (code < 400) {
+ if (settings_1.TwitterApiV2Settings.debug) {
+ settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
+ }
+ const dataStream = this.getResponseDataStream(res);
+ // HTTP code ok, consume stream
+ resolve({ req: this.req, res: dataStream, originalResponse: res, requestData: this.requestData });
+ }
+ else {
+ // Handle response normally, can only rejects
+ this.classicResponseHandler(() => undefined, reject, res);
+ }
+ }
+ /* Wrappers for request lifecycle */
+ debugRequest() {
+ const url = this.requestData.url;
+ settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options);
+ if (url.search) {
+ settings_1.TwitterApiV2Settings.logger.log('Request parameters:', [...url.searchParams.entries()].map(([key, value]) => `${key}: ${value}`));
+ }
+ if (this.requestData.body) {
+ settings_1.TwitterApiV2Settings.logger.log('Request body:', this.requestData.body);
+ }
+ }
+ buildRequest() {
+ var _a;
+ const url = this.requestData.url;
+ const auth = url.username ? `${url.username}:${url.password}` : undefined;
+ const headers = (_a = this.requestData.options.headers) !== null && _a !== void 0 ? _a : {};
+ if (this.requestData.compression === true || this.requestData.compression === 'brotli') {
+ headers['accept-encoding'] = 'br;q=1.0, gzip;q=0.8, deflate;q=0.5, *;q=0.1';
+ }
+ else if (this.requestData.compression === 'gzip') {
+ headers['accept-encoding'] = 'gzip;q=1, deflate;q=0.5, *;q=0.1';
+ }
+ else if (this.requestData.compression === 'deflate') {
+ headers['accept-encoding'] = 'deflate;q=1, *;q=0.1';
+ }
+ if (settings_1.TwitterApiV2Settings.debug) {
+ this.debugRequest();
+ }
+ this.req = (0, https_1.request)({
+ ...this.requestData.options,
+ // Define URL params manually, addresses dependencies error https://github.com/PLhery/node-twitter-api-v2/issues/94
+ host: url.hostname,
+ port: url.port || undefined,
+ path: url.pathname + url.search,
+ protocol: url.protocol,
+ auth,
+ headers,
+ });
+ }
+ registerRequestEventDebugHandlers(req) {
+ req.on('close', () => this.requestData.requestEventDebugHandler('close'));
+ req.on('abort', () => this.requestData.requestEventDebugHandler('abort'));
+ req.on('socket', socket => {
+ this.requestData.requestEventDebugHandler('socket', { socket });
+ socket.on('error', error => this.requestData.requestEventDebugHandler('socket-error', { socket, error }));
+ socket.on('connect', () => this.requestData.requestEventDebugHandler('socket-connect', { socket }));
+ socket.on('close', withError => this.requestData.requestEventDebugHandler('socket-close', { socket, withError }));
+ socket.on('end', () => this.requestData.requestEventDebugHandler('socket-end', { socket }));
+ socket.on('lookup', (...data) => this.requestData.requestEventDebugHandler('socket-lookup', { socket, data }));
+ socket.on('timeout', () => this.requestData.requestEventDebugHandler('socket-timeout', { socket }));
+ });
+ }
+ makeRequest() {
+ this.buildRequest();
+ return new Promise((resolve, reject) => {
+ const req = this.req;
+ // Handle request errors
+ req.on('error', this.requestErrorHandler.bind(this, reject));
+ req.on('socket', this.onSocketEventHandler.bind(this, reject));
+ req.on('response', this.classicResponseHandler.bind(this, resolve, reject));
+ if (this.requestData.options.timeout) {
+ req.on('timeout', this.timeoutErrorHandler.bind(this));
+ }
+ // Debug handlers
+ if (this.requestData.requestEventDebugHandler) {
+ this.registerRequestEventDebugHandlers(req);
+ }
+ if (this.requestData.body) {
+ req.write(this.requestData.body);
+ }
+ req.end();
+ });
+ }
+ async makeRequestAsStream() {
+ const { req, res, requestData, originalResponse } = await this.makeRequestAndResolveWhenReady();
+ return new TweetStream_1.default(requestData, { req, res, originalResponse });
+ }
+ makeRequestAndResolveWhenReady() {
+ this.buildRequest();
+ return new Promise((resolve, reject) => {
+ const req = this.req;
+ // Handle request errors
+ req.on('error', this.requestErrorHandler.bind(this, reject));
+ req.on('response', this.streamResponseHandler.bind(this, resolve, reject));
+ if (this.requestData.body) {
+ req.write(this.requestData.body);
+ }
+ req.end();
+ });
+ }
+}
+exports.RequestHandlerHelper = RequestHandlerHelper;
+exports.default = RequestHandlerHelper;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.d.ts
new file mode 100644
index 0000000..f4160c4
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.d.ts
@@ -0,0 +1,58 @@
+///
+import { IClientSettings, ITwitterApiClientPlugin, TClientTokens, TwitterApiPluginResponseOverride, TwitterRateLimit, TwitterResponse } from '../types';
+import TweetStream from '../stream/TweetStream';
+import type { ClientRequestArgs } from 'http';
+import OAuth1Helper from './oauth1.helper';
+import type { IGetHttpRequestArgs, IGetStreamRequestArgs, IGetStreamRequestArgsAsync, IGetStreamRequestArgsSync, IWriteAuthHeadersArgs, TAcceptedInitToken } from '../types/request-maker.mixin.types';
+import { IComputedHttpRequestArgs } from '../types/request-maker.mixin.types';
+export declare class ClientRequestMaker {
+ bearerToken?: string;
+ consumerToken?: string;
+ consumerSecret?: string;
+ accessToken?: string;
+ accessSecret?: string;
+ basicToken?: string;
+ clientId?: string;
+ clientSecret?: string;
+ rateLimits: {
+ [endpoint: string]: TwitterRateLimit;
+ };
+ clientSettings: Partial;
+ protected _oauth?: OAuth1Helper;
+ protected static readonly BODY_METHODS: Set;
+ constructor(settings?: Partial);
+ /** @deprecated - Switch to `@twitter-api-v2/plugin-rate-limit` */
+ getRateLimits(): {
+ [endpoint: string]: TwitterRateLimit;
+ };
+ protected saveRateLimit(originalUrl: string, rateLimit: TwitterRateLimit): void;
+ /** Send a new request and returns a wrapped `Promise`. */
+ send(requestParams: IGetHttpRequestArgs): Promise>;
+ /**
+ * Create a new request, then creates a stream from it as a `TweetStream`.
+ *
+ * Request will be sent only if `autoConnect` is not set or `true`: return type will be `Promise`.
+ * If `autoConnect` is `false`, a `TweetStream` is directly returned and you should call `stream.connect()` by yourself.
+ */
+ sendStream(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgsSync): TweetStream;
+ sendStream(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgsAsync): Promise>;
+ sendStream(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgs): Promise> | TweetStream;
+ initializeToken(token?: TAcceptedInitToken): void;
+ getActiveTokens(): TClientTokens;
+ protected buildOAuth(): OAuth1Helper;
+ protected getOAuthAccessTokens(): {
+ key: string;
+ secret: string;
+ } | undefined;
+ getPlugins(): ITwitterApiClientPlugin[];
+ hasPlugins(): boolean;
+ applyPluginMethod(method: K, args: Parameters[K]>[0]): Promise;
+ protected writeAuthHeaders({ headers, bodyInSignature, url, method, query, body }: IWriteAuthHeadersArgs): Record;
+ protected getUrlObjectFromUrlString(url: string): URL;
+ protected getHttpRequestArgs({ url: stringUrl, method, query: rawQuery, body: rawBody, headers, forceBodyMode, enableAuth, params, }: IGetHttpRequestArgs): IComputedHttpRequestArgs;
+ protected applyPreRequestConfigHooks(requestParams: IGetHttpRequestArgs): Promise | undefined>;
+ protected applyPreStreamRequestConfigHooks(requestParams: IGetHttpRequestArgs): void;
+ protected applyPreRequestHooks(requestParams: IGetHttpRequestArgs, computedParams: IComputedHttpRequestArgs, requestOptions: Partial): Promise;
+ protected applyPostRequestHooks(requestParams: IGetHttpRequestArgs, computedParams: IComputedHttpRequestArgs, requestOptions: Partial, response: TwitterResponse): Promise;
+ protected applyResponseErrorHooks(requestParams: IGetHttpRequestArgs, computedParams: IComputedHttpRequestArgs, requestOptions: Partial, promise: Promise>): Promise>;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.js
new file mode 100644
index 0000000..3dab72f
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-maker.mixin.js
@@ -0,0 +1,323 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ClientRequestMaker = void 0;
+const types_1 = require("../types");
+const TweetStream_1 = __importDefault(require("../stream/TweetStream"));
+const helpers_1 = require("../plugins/helpers");
+const helpers_2 = require("../helpers");
+const oauth1_helper_1 = __importDefault(require("./oauth1.helper"));
+const request_handler_helper_1 = __importDefault(require("./request-handler.helper"));
+const request_param_helper_1 = __importDefault(require("./request-param.helper"));
+const oauth2_helper_1 = require("./oauth2.helper");
+class ClientRequestMaker {
+ constructor(settings) {
+ this.rateLimits = {};
+ this.clientSettings = {};
+ if (settings) {
+ this.clientSettings = settings;
+ }
+ }
+ /** @deprecated - Switch to `@twitter-api-v2/plugin-rate-limit` */
+ getRateLimits() {
+ return this.rateLimits;
+ }
+ saveRateLimit(originalUrl, rateLimit) {
+ this.rateLimits[originalUrl] = rateLimit;
+ }
+ /** Send a new request and returns a wrapped `Promise`. */
+ async send(requestParams) {
+ var _a, _b, _c, _d, _e;
+ // Pre-request config hooks
+ if ((_a = this.clientSettings.plugins) === null || _a === void 0 ? void 0 : _a.length) {
+ const possibleResponse = await this.applyPreRequestConfigHooks(requestParams);
+ if (possibleResponse) {
+ return possibleResponse;
+ }
+ }
+ const args = this.getHttpRequestArgs(requestParams);
+ const options = {
+ method: args.method,
+ headers: args.headers,
+ timeout: requestParams.timeout,
+ agent: this.clientSettings.httpAgent,
+ };
+ const enableRateLimitSave = requestParams.enableRateLimitSave !== false;
+ if (args.body) {
+ request_param_helper_1.default.setBodyLengthHeader(options, args.body);
+ }
+ // Pre-request hooks
+ if ((_b = this.clientSettings.plugins) === null || _b === void 0 ? void 0 : _b.length) {
+ await this.applyPreRequestHooks(requestParams, args, options);
+ }
+ let request = new request_handler_helper_1.default({
+ url: args.url,
+ options,
+ body: args.body,
+ rateLimitSaver: enableRateLimitSave ? this.saveRateLimit.bind(this, args.rawUrl) : undefined,
+ requestEventDebugHandler: requestParams.requestEventDebugHandler,
+ compression: (_d = (_c = requestParams.compression) !== null && _c !== void 0 ? _c : this.clientSettings.compression) !== null && _d !== void 0 ? _d : true,
+ forceParseMode: requestParams.forceParseMode,
+ })
+ .makeRequest();
+ if ((0, helpers_1.hasRequestErrorPlugins)(this)) {
+ request = this.applyResponseErrorHooks(requestParams, args, options, request);
+ }
+ const response = await request;
+ // Post-request hooks
+ if ((_e = this.clientSettings.plugins) === null || _e === void 0 ? void 0 : _e.length) {
+ const responseOverride = await this.applyPostRequestHooks(requestParams, args, options, response);
+ if (responseOverride) {
+ return responseOverride.value;
+ }
+ }
+ return response;
+ }
+ sendStream(requestParams) {
+ var _a, _b;
+ // Pre-request hooks
+ if (this.clientSettings.plugins) {
+ this.applyPreStreamRequestConfigHooks(requestParams);
+ }
+ const args = this.getHttpRequestArgs(requestParams);
+ const options = {
+ method: args.method,
+ headers: args.headers,
+ agent: this.clientSettings.httpAgent,
+ };
+ const enableRateLimitSave = requestParams.enableRateLimitSave !== false;
+ const enableAutoConnect = requestParams.autoConnect !== false;
+ if (args.body) {
+ request_param_helper_1.default.setBodyLengthHeader(options, args.body);
+ }
+ const requestData = {
+ url: args.url,
+ options,
+ body: args.body,
+ rateLimitSaver: enableRateLimitSave ? this.saveRateLimit.bind(this, args.rawUrl) : undefined,
+ payloadIsError: requestParams.payloadIsError,
+ compression: (_b = (_a = requestParams.compression) !== null && _a !== void 0 ? _a : this.clientSettings.compression) !== null && _b !== void 0 ? _b : true,
+ };
+ const stream = new TweetStream_1.default(requestData);
+ if (!enableAutoConnect) {
+ return stream;
+ }
+ return stream.connect();
+ }
+ /* Token helpers */
+ initializeToken(token) {
+ if (typeof token === 'string') {
+ this.bearerToken = token;
+ }
+ else if (typeof token === 'object' && 'appKey' in token) {
+ this.consumerToken = token.appKey;
+ this.consumerSecret = token.appSecret;
+ if (token.accessToken && token.accessSecret) {
+ this.accessToken = token.accessToken;
+ this.accessSecret = token.accessSecret;
+ }
+ this._oauth = this.buildOAuth();
+ }
+ else if (typeof token === 'object' && 'username' in token) {
+ const key = encodeURIComponent(token.username) + ':' + encodeURIComponent(token.password);
+ this.basicToken = Buffer.from(key).toString('base64');
+ }
+ else if (typeof token === 'object' && 'clientId' in token) {
+ this.clientId = token.clientId;
+ this.clientSecret = token.clientSecret;
+ }
+ }
+ getActiveTokens() {
+ if (this.bearerToken) {
+ return {
+ type: 'oauth2',
+ bearerToken: this.bearerToken,
+ };
+ }
+ else if (this.basicToken) {
+ return {
+ type: 'basic',
+ token: this.basicToken,
+ };
+ }
+ else if (this.consumerSecret && this._oauth) {
+ return {
+ type: 'oauth-1.0a',
+ appKey: this.consumerToken,
+ appSecret: this.consumerSecret,
+ accessToken: this.accessToken,
+ accessSecret: this.accessSecret,
+ };
+ }
+ else if (this.clientId) {
+ return {
+ type: 'oauth2-user',
+ clientId: this.clientId,
+ };
+ }
+ return { type: 'none' };
+ }
+ buildOAuth() {
+ if (!this.consumerSecret || !this.consumerToken)
+ throw new Error('Invalid consumer tokens');
+ return new oauth1_helper_1.default({
+ consumerKeys: { key: this.consumerToken, secret: this.consumerSecret },
+ });
+ }
+ getOAuthAccessTokens() {
+ if (!this.accessSecret || !this.accessToken)
+ return;
+ return {
+ key: this.accessToken,
+ secret: this.accessSecret,
+ };
+ }
+ /* Plugin helpers */
+ getPlugins() {
+ var _a;
+ return (_a = this.clientSettings.plugins) !== null && _a !== void 0 ? _a : [];
+ }
+ hasPlugins() {
+ var _a;
+ return !!((_a = this.clientSettings.plugins) === null || _a === void 0 ? void 0 : _a.length);
+ }
+ async applyPluginMethod(method, args) {
+ var _a;
+ let returnValue;
+ for (const plugin of this.getPlugins()) {
+ const value = await ((_a = plugin[method]) === null || _a === void 0 ? void 0 : _a.call(plugin, args));
+ if (value && value instanceof types_1.TwitterApiPluginResponseOverride) {
+ returnValue = value;
+ }
+ }
+ return returnValue;
+ }
+ /* Request helpers */
+ writeAuthHeaders({ headers, bodyInSignature, url, method, query, body }) {
+ headers = { ...headers };
+ if (this.bearerToken) {
+ headers.Authorization = 'Bearer ' + this.bearerToken;
+ }
+ else if (this.basicToken) {
+ // Basic auth, to request a bearer token
+ headers.Authorization = 'Basic ' + this.basicToken;
+ }
+ else if (this.clientId && this.clientSecret) {
+ // Basic auth with clientId + clientSecret
+ headers.Authorization = 'Basic ' + oauth2_helper_1.OAuth2Helper.getAuthHeader(this.clientId, this.clientSecret);
+ }
+ else if (this.consumerSecret && this._oauth) {
+ // Merge query and body
+ const data = bodyInSignature ? request_param_helper_1.default.mergeQueryAndBodyForOAuth(query, body) : query;
+ const auth = this._oauth.authorize({
+ url: url.toString(),
+ method,
+ data,
+ }, this.getOAuthAccessTokens());
+ headers = { ...headers, ...this._oauth.toHeader(auth) };
+ }
+ return headers;
+ }
+ getUrlObjectFromUrlString(url) {
+ // Add protocol to URL if needed
+ if (!url.startsWith('http')) {
+ url = 'https://' + url;
+ }
+ // Convert URL to object that will receive all URL modifications
+ return new URL(url);
+ }
+ getHttpRequestArgs({ url: stringUrl, method, query: rawQuery = {}, body: rawBody = {}, headers, forceBodyMode, enableAuth, params, }) {
+ let body = undefined;
+ method = method.toUpperCase();
+ headers = headers !== null && headers !== void 0 ? headers : {};
+ // Add user agent header (Twitter recommends it)
+ if (!headers['x-user-agent']) {
+ headers['x-user-agent'] = 'Node.twitter-api-v2';
+ }
+ const url = this.getUrlObjectFromUrlString(stringUrl);
+ // URL without query string to save as endpoint name
+ const rawUrl = url.origin + url.pathname;
+ // Apply URL parameters
+ if (params) {
+ request_param_helper_1.default.applyRequestParametersToUrl(url, params);
+ }
+ // Build a URL without anything in QS, and QSP in query
+ const query = request_param_helper_1.default.formatQueryToString(rawQuery);
+ request_param_helper_1.default.moveUrlQueryParamsIntoObject(url, query);
+ // Delete undefined parameters
+ if (!(rawBody instanceof Buffer)) {
+ (0, helpers_2.trimUndefinedProperties)(rawBody);
+ }
+ // OAuth signature should not include parameters when using multipart.
+ const bodyType = forceBodyMode !== null && forceBodyMode !== void 0 ? forceBodyMode : request_param_helper_1.default.autoDetectBodyType(url);
+ // If undefined or true, enable auth by headers
+ if (enableAuth !== false) {
+ // OAuth needs body signature only if body is URL encoded.
+ const bodyInSignature = ClientRequestMaker.BODY_METHODS.has(method) && bodyType === 'url';
+ headers = this.writeAuthHeaders({ headers, bodyInSignature, method, query, url, body: rawBody });
+ }
+ if (ClientRequestMaker.BODY_METHODS.has(method)) {
+ body = request_param_helper_1.default.constructBodyParams(rawBody, headers, bodyType) || undefined;
+ }
+ request_param_helper_1.default.addQueryParamsToUrl(url, query);
+ return {
+ rawUrl,
+ url,
+ method,
+ headers,
+ body,
+ };
+ }
+ /* Plugin helpers */
+ async applyPreRequestConfigHooks(requestParams) {
+ var _a;
+ const url = this.getUrlObjectFromUrlString(requestParams.url);
+ for (const plugin of this.getPlugins()) {
+ const result = await ((_a = plugin.onBeforeRequestConfig) === null || _a === void 0 ? void 0 : _a.call(plugin, {
+ client: this,
+ url,
+ params: requestParams,
+ }));
+ if (result) {
+ return result;
+ }
+ }
+ }
+ applyPreStreamRequestConfigHooks(requestParams) {
+ var _a;
+ const url = this.getUrlObjectFromUrlString(requestParams.url);
+ for (const plugin of this.getPlugins()) {
+ (_a = plugin.onBeforeStreamRequestConfig) === null || _a === void 0 ? void 0 : _a.call(plugin, {
+ client: this,
+ url,
+ params: requestParams,
+ });
+ }
+ }
+ async applyPreRequestHooks(requestParams, computedParams, requestOptions) {
+ await this.applyPluginMethod('onBeforeRequest', {
+ client: this,
+ url: this.getUrlObjectFromUrlString(requestParams.url),
+ params: requestParams,
+ computedParams,
+ requestOptions,
+ });
+ }
+ async applyPostRequestHooks(requestParams, computedParams, requestOptions, response) {
+ return await this.applyPluginMethod('onAfterRequest', {
+ client: this,
+ url: this.getUrlObjectFromUrlString(requestParams.url),
+ params: requestParams,
+ computedParams,
+ requestOptions,
+ response,
+ });
+ }
+ applyResponseErrorHooks(requestParams, computedParams, requestOptions, promise) {
+ return promise.catch(helpers_1.applyResponseHooks.bind(this, requestParams, computedParams, requestOptions));
+ }
+}
+exports.ClientRequestMaker = ClientRequestMaker;
+ClientRequestMaker.BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.d.ts
new file mode 100644
index 0000000..7c220e0
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.d.ts
@@ -0,0 +1,21 @@
+///
+///
+import type { RequestOptions } from 'https';
+import type { TBodyMode, TRequestBody, TRequestQuery, TRequestStringQuery } from '../types/request-maker.mixin.types';
+export declare class RequestParamHelpers {
+ static readonly JSON_1_1_ENDPOINTS: Set;
+ static formatQueryToString(query: TRequestQuery): TRequestStringQuery;
+ static autoDetectBodyType(url: URL): TBodyMode;
+ static addQueryParamsToUrl(url: URL, query: TRequestQuery): void;
+ static constructBodyParams(body: TRequestBody, headers: Record, mode: TBodyMode): string | Buffer;
+ static setBodyLengthHeader(options: RequestOptions, body: string | Buffer): void;
+ static isOAuthSerializable(item: any): boolean;
+ static mergeQueryAndBodyForOAuth(query: TRequestQuery, body: TRequestBody): any;
+ static moveUrlQueryParamsIntoObject(url: URL, query: TRequestQuery): URL;
+ /**
+ * Replace URL parameters available in pathname, like `:id`, with data given in `parameters`:
+ * `https://twitter.com/:id.json` + `{ id: '20' }` => `https://twitter.com/20.json`
+ */
+ static applyRequestParametersToUrl(url: URL, parameters: TRequestQuery): URL;
+}
+export default RequestParamHelpers;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.js b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.js
new file mode 100644
index 0000000..60c56ce
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client-mixins/request-param.helper.js
@@ -0,0 +1,151 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RequestParamHelpers = void 0;
+const form_data_helper_1 = require("./form-data.helper");
+const oauth1_helper_1 = __importDefault(require("./oauth1.helper"));
+/* Helpers functions that are specific to this class but do not depends on instance */
+class RequestParamHelpers {
+ static formatQueryToString(query) {
+ const formattedQuery = {};
+ for (const prop in query) {
+ if (typeof query[prop] === 'string') {
+ formattedQuery[prop] = query[prop];
+ }
+ else if (typeof query[prop] !== 'undefined') {
+ formattedQuery[prop] = String(query[prop]);
+ }
+ }
+ return formattedQuery;
+ }
+ static autoDetectBodyType(url) {
+ if (url.pathname.startsWith('/2/') || url.pathname.startsWith('/labs/2/')) {
+ // oauth2 takes url encoded
+ if (url.password.startsWith('/2/oauth2')) {
+ return 'url';
+ }
+ // Twitter API v2 has JSON-encoded requests for everything else
+ return 'json';
+ }
+ if (url.hostname === 'upload.twitter.com') {
+ if (url.pathname === '/1.1/media/upload.json') {
+ return 'form-data';
+ }
+ // json except for media/upload command, that is form-data.
+ return 'json';
+ }
+ const endpoint = url.pathname.split('/1.1/', 2)[1];
+ if (this.JSON_1_1_ENDPOINTS.has(endpoint)) {
+ return 'json';
+ }
+ return 'url';
+ }
+ static addQueryParamsToUrl(url, query) {
+ const queryEntries = Object.entries(query);
+ if (queryEntries.length) {
+ let search = '';
+ for (const [key, value] of queryEntries) {
+ search += (search.length ? '&' : '?') + `${oauth1_helper_1.default.percentEncode(key)}=${oauth1_helper_1.default.percentEncode(value)}`;
+ }
+ url.search = search;
+ }
+ }
+ static constructBodyParams(body, headers, mode) {
+ if (body instanceof Buffer) {
+ return body;
+ }
+ if (mode === 'json') {
+ if (!headers['content-type']) {
+ headers['content-type'] = 'application/json;charset=UTF-8';
+ }
+ return JSON.stringify(body);
+ }
+ else if (mode === 'url') {
+ if (!headers['content-type']) {
+ headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
+ }
+ if (Object.keys(body).length) {
+ return new URLSearchParams(body)
+ .toString()
+ .replace(/\*/g, '%2A'); // URLSearchParams doesnt encode '*', but Twitter wants it encoded.
+ }
+ return '';
+ }
+ else if (mode === 'raw') {
+ throw new Error('You can only use raw body mode with Buffers. To give a string, use Buffer.from(str).');
+ }
+ else {
+ const form = new form_data_helper_1.FormDataHelper();
+ for (const parameter in body) {
+ form.append(parameter, body[parameter]);
+ }
+ if (!headers['content-type']) {
+ const formHeaders = form.getHeaders();
+ headers['content-type'] = formHeaders['content-type'];
+ }
+ return form.getBuffer();
+ }
+ }
+ static setBodyLengthHeader(options, body) {
+ var _a;
+ options.headers = (_a = options.headers) !== null && _a !== void 0 ? _a : {};
+ if (typeof body === 'string') {
+ options.headers['content-length'] = Buffer.byteLength(body);
+ }
+ else {
+ options.headers['content-length'] = body.length;
+ }
+ }
+ static isOAuthSerializable(item) {
+ return !(item instanceof Buffer);
+ }
+ static mergeQueryAndBodyForOAuth(query, body) {
+ const parameters = {};
+ for (const prop in query) {
+ parameters[prop] = query[prop];
+ }
+ if (this.isOAuthSerializable(body)) {
+ for (const prop in body) {
+ const bodyProp = body[prop];
+ if (this.isOAuthSerializable(bodyProp)) {
+ parameters[prop] = typeof bodyProp === 'object' && bodyProp !== null && 'toString' in bodyProp
+ ? bodyProp.toString()
+ : bodyProp;
+ }
+ }
+ }
+ return parameters;
+ }
+ static moveUrlQueryParamsIntoObject(url, query) {
+ for (const [param, value] of url.searchParams) {
+ query[param] = value;
+ }
+ // Remove the query string
+ url.search = '';
+ return url;
+ }
+ /**
+ * Replace URL parameters available in pathname, like `:id`, with data given in `parameters`:
+ * `https://twitter.com/:id.json` + `{ id: '20' }` => `https://twitter.com/20.json`
+ */
+ static applyRequestParametersToUrl(url, parameters) {
+ url.pathname = url.pathname.replace(/:([A-Z_-]+)/ig, (fullMatch, paramName) => {
+ if (parameters[paramName] !== undefined) {
+ return String(parameters[paramName]);
+ }
+ return fullMatch;
+ });
+ return url;
+ }
+}
+exports.RequestParamHelpers = RequestParamHelpers;
+RequestParamHelpers.JSON_1_1_ENDPOINTS = new Set([
+ 'direct_messages/events/new.json',
+ 'direct_messages/welcome_messages/new.json',
+ 'direct_messages/welcome_messages/rules/new.json',
+ 'media/metadata/create.json',
+ 'collections/entries/curate.json',
+]);
+exports.default = RequestParamHelpers;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client.base.d.ts b/node_modules/twitter-api-v2/dist/cjs/client.base.d.ts
new file mode 100644
index 0000000..2bc89c2
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client.base.d.ts
@@ -0,0 +1,134 @@
+import type { IClientSettings, ITwitterApiClientPlugin, TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens, TwitterRateLimit, TwitterResponse, UserV1, UserV2Result } from './types';
+import { ClientRequestMaker } from './client-mixins/request-maker.mixin';
+import TweetStream from './stream/TweetStream';
+import { SharedPromise } from './helpers';
+import type { TCustomizableRequestArgs, TRequestBody, TRequestQuery } from './types/request-maker.mixin.types';
+export declare type TGetClientRequestArgs = TCustomizableRequestArgs & {
+ prefix?: string;
+ fullResponse?: boolean;
+};
+declare type TGetClientRequestArgsFullResponse = TClientRequestArgs & {
+ fullResponse: true;
+};
+declare type TGetClientRequestArgsDataResponse = TClientRequestArgs & {
+ fullResponse?: false;
+};
+export declare type TClientRequestArgs = TCustomizableRequestArgs & {
+ prefix?: string;
+ fullResponse?: boolean;
+ query?: TRequestQuery;
+};
+declare type TClientRequestArgsFullResponse = TClientRequestArgs & {
+ fullResponse: true;
+};
+declare type TClientRequestArgsDataResponse = TClientRequestArgs & {
+ fullResponse?: false;
+};
+export declare type TStreamClientRequestArgs = TCustomizableRequestArgs & {
+ prefix?: string;
+ query?: TRequestQuery;
+ payloadIsError?: (data: any) => boolean;
+ /**
+ * Choose to make or not initial connection.
+ * Method `.connect` must be called on returned `TweetStream` object
+ * to start stream if `autoConnect` is set to `false`.
+ * Defaults to `true`.
+ */
+ autoConnect?: boolean;
+};
+export declare type TStreamClientRequestArgsWithAutoConnect = TStreamClientRequestArgs & {
+ autoConnect?: true;
+};
+export declare type TStreamClientRequestArgsWithoutAutoConnect = TStreamClientRequestArgs & {
+ autoConnect: false;
+};
+/**
+ * Base class for Twitter instances
+ */
+export default abstract class TwitterApiBase {
+ protected _prefix: string | undefined;
+ protected _currentUser: SharedPromise | null;
+ protected _currentUserV2: SharedPromise | null;
+ protected _requestMaker: ClientRequestMaker;
+ /**
+ * Create a new TwitterApi object without authentication.
+ */
+ constructor(_?: undefined, settings?: Partial);
+ /**
+ * Create a new TwitterApi object with OAuth 2.0 Bearer authentication.
+ */
+ constructor(bearerToken: string, settings?: Partial);
+ /**
+ * Create a new TwitterApi object with three-legged OAuth 1.0a authentication.
+ */
+ constructor(tokens: TwitterApiTokens, settings?: Partial);
+ /**
+ * Create a new TwitterApi object with only client ID needed for OAuth2 user-flow.
+ */
+ constructor(oauth2Init: TwitterApiOAuth2Init, settings?: Partial);
+ /**
+ * Create a new TwitterApi object with Basic HTTP authentication.
+ */
+ constructor(credentials: TwitterApiBasicAuth, settings?: Partial);
+ /**
+ * Create a clone of {instance}.
+ */
+ constructor(instance: TwitterApiBase, settings?: Partial);
+ protected setPrefix(prefix: string | undefined): void;
+ cloneWithPrefix(prefix: string): this;
+ getActiveTokens(): import("./types").TClientTokens;
+ getPlugins(): ITwitterApiClientPlugin[];
+ getPluginOfType(type: {
+ new (...args: any[]): T;
+ }): T | undefined;
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Tells if you hit the Twitter rate limit for {endpoint}.
+ * (local data only, this should not ask anything to Twitter)
+ */
+ hasHitRateLimit(endpoint: string): boolean;
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Tells if you hit the returned Twitter rate limit for {endpoint} has expired.
+ * If client has no saved rate limit data for {endpoint}, this will gives you `true`.
+ */
+ isRateLimitStatusObsolete(endpoint: string): boolean;
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Get the last obtained Twitter rate limit information for {endpoint}.
+ * (local data only, this should not ask anything to Twitter)
+ */
+ getLastRateLimitStatus(endpoint: string): TwitterRateLimit | undefined;
+ /** Get cached current user. */
+ protected getCurrentUserObject(forceFetch?: boolean): Promise;
+ /**
+ * Get cached current user from v2 API.
+ * This can only be the slimest available `UserV2` object, with only `id`, `name` and `username` properties defined.
+ *
+ * To get a customized `UserV2Result`, use `.v2.me()`
+ *
+ * OAuth2 scopes: `tweet.read` & `users.read`
+ */
+ protected getCurrentUserV2Object(forceFetch?: boolean): Promise;
+ get(url: string, query?: TRequestQuery, args?: TGetClientRequestArgsDataResponse): Promise;
+ get(url: string, query?: TRequestQuery, args?: TGetClientRequestArgsFullResponse): Promise>;
+ delete(url: string, query?: TRequestQuery, args?: TGetClientRequestArgsDataResponse): Promise;
+ delete(url: string, query?: TRequestQuery, args?: TGetClientRequestArgsFullResponse): Promise>;
+ post(url: string, body?: TRequestBody, args?: TClientRequestArgsDataResponse): Promise;
+ post(url: string, body?: TRequestBody, args?: TClientRequestArgsFullResponse): Promise>;
+ put(url: string, body?: TRequestBody, args?: TClientRequestArgsDataResponse): Promise;
+ put(url: string, body?: TRequestBody, args?: TClientRequestArgsFullResponse): Promise>;
+ patch(url: string, body?: TRequestBody, args?: TClientRequestArgsDataResponse): Promise;
+ patch(url: string, body?: TRequestBody, args?: TClientRequestArgsFullResponse): Promise>;
+ /** Stream request helpers */
+ getStream(url: string, query: TRequestQuery | undefined, options: TStreamClientRequestArgsWithoutAutoConnect): TweetStream;
+ getStream(url: string, query?: TRequestQuery, options?: TStreamClientRequestArgsWithAutoConnect): Promise>;
+ getStream(url: string, query?: TRequestQuery, options?: TStreamClientRequestArgs): Promise> | TweetStream;
+ postStream(url: string, body: TRequestBody | undefined, options: TStreamClientRequestArgsWithoutAutoConnect): TweetStream;
+ postStream(url: string, body?: TRequestBody, options?: TStreamClientRequestArgsWithAutoConnect): Promise>;
+ postStream(url: string, body?: TRequestBody, options?: TStreamClientRequestArgs): Promise> | TweetStream;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/client.base.js b/node_modules/twitter-api-v2/dist/cjs/client.base.js
new file mode 100644
index 0000000..926fb56
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client.base.js
@@ -0,0 +1,179 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const request_maker_mixin_1 = require("./client-mixins/request-maker.mixin");
+const helpers_1 = require("./helpers");
+const globals_1 = require("./globals");
+/**
+ * Base class for Twitter instances
+ */
+class TwitterApiBase {
+ constructor(token, settings = {}) {
+ this._currentUser = null;
+ this._currentUserV2 = null;
+ if (token instanceof TwitterApiBase) {
+ this._requestMaker = token._requestMaker;
+ }
+ else {
+ this._requestMaker = new request_maker_mixin_1.ClientRequestMaker(settings);
+ this._requestMaker.initializeToken(token);
+ }
+ }
+ /* Prefix/Token handling */
+ setPrefix(prefix) {
+ this._prefix = prefix;
+ }
+ cloneWithPrefix(prefix) {
+ const clone = this.constructor(this);
+ clone.setPrefix(prefix);
+ return clone;
+ }
+ getActiveTokens() {
+ return this._requestMaker.getActiveTokens();
+ }
+ /* Rate limit cache / Plugins */
+ getPlugins() {
+ return this._requestMaker.getPlugins();
+ }
+ getPluginOfType(type) {
+ return this.getPlugins().find(plugin => plugin instanceof type);
+ }
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Tells if you hit the Twitter rate limit for {endpoint}.
+ * (local data only, this should not ask anything to Twitter)
+ */
+ hasHitRateLimit(endpoint) {
+ var _a;
+ if (this.isRateLimitStatusObsolete(endpoint)) {
+ return false;
+ }
+ return ((_a = this.getLastRateLimitStatus(endpoint)) === null || _a === void 0 ? void 0 : _a.remaining) === 0;
+ }
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Tells if you hit the returned Twitter rate limit for {endpoint} has expired.
+ * If client has no saved rate limit data for {endpoint}, this will gives you `true`.
+ */
+ isRateLimitStatusObsolete(endpoint) {
+ const rateLimit = this.getLastRateLimitStatus(endpoint);
+ if (rateLimit === undefined) {
+ return true;
+ }
+ // Timestamps are exprimed in seconds, JS works with ms
+ return (rateLimit.reset * 1000) < Date.now();
+ }
+ /**
+ * @deprecated - Migrate to plugin `@twitter-api-v2/plugin-rate-limit`
+ *
+ * Get the last obtained Twitter rate limit information for {endpoint}.
+ * (local data only, this should not ask anything to Twitter)
+ */
+ getLastRateLimitStatus(endpoint) {
+ const endpointWithPrefix = endpoint.match(/^https?:\/\//) ? endpoint : (this._prefix + endpoint);
+ return this._requestMaker.getRateLimits()[endpointWithPrefix];
+ }
+ /* Current user cache */
+ /** Get cached current user. */
+ getCurrentUserObject(forceFetch = false) {
+ if (!forceFetch && this._currentUser) {
+ if (this._currentUser.value) {
+ return Promise.resolve(this._currentUser.value);
+ }
+ return this._currentUser.promise;
+ }
+ this._currentUser = (0, helpers_1.sharedPromise)(() => this.get('account/verify_credentials.json', { tweet_mode: 'extended' }, { prefix: globals_1.API_V1_1_PREFIX }));
+ return this._currentUser.promise;
+ }
+ /**
+ * Get cached current user from v2 API.
+ * This can only be the slimest available `UserV2` object, with only `id`, `name` and `username` properties defined.
+ *
+ * To get a customized `UserV2Result`, use `.v2.me()`
+ *
+ * OAuth2 scopes: `tweet.read` & `users.read`
+ */
+ getCurrentUserV2Object(forceFetch = false) {
+ if (!forceFetch && this._currentUserV2) {
+ if (this._currentUserV2.value) {
+ return Promise.resolve(this._currentUserV2.value);
+ }
+ return this._currentUserV2.promise;
+ }
+ this._currentUserV2 = (0, helpers_1.sharedPromise)(() => this.get('users/me', undefined, { prefix: globals_1.API_V2_PREFIX }));
+ return this._currentUserV2.promise;
+ }
+ async get(url, query = {}, { fullResponse, prefix = this._prefix, ...rest } = {}) {
+ if (prefix)
+ url = prefix + url;
+ const resp = await this._requestMaker.send({
+ url,
+ method: 'GET',
+ query,
+ ...rest,
+ });
+ return fullResponse ? resp : resp.data;
+ }
+ async delete(url, query = {}, { fullResponse, prefix = this._prefix, ...rest } = {}) {
+ if (prefix)
+ url = prefix + url;
+ const resp = await this._requestMaker.send({
+ url,
+ method: 'DELETE',
+ query,
+ ...rest,
+ });
+ return fullResponse ? resp : resp.data;
+ }
+ async post(url, body, { fullResponse, prefix = this._prefix, ...rest } = {}) {
+ if (prefix)
+ url = prefix + url;
+ const resp = await this._requestMaker.send({
+ url,
+ method: 'POST',
+ body,
+ ...rest,
+ });
+ return fullResponse ? resp : resp.data;
+ }
+ async put(url, body, { fullResponse, prefix = this._prefix, ...rest } = {}) {
+ if (prefix)
+ url = prefix + url;
+ const resp = await this._requestMaker.send({
+ url,
+ method: 'PUT',
+ body,
+ ...rest,
+ });
+ return fullResponse ? resp : resp.data;
+ }
+ async patch(url, body, { fullResponse, prefix = this._prefix, ...rest } = {}) {
+ if (prefix)
+ url = prefix + url;
+ const resp = await this._requestMaker.send({
+ url,
+ method: 'PATCH',
+ body,
+ ...rest,
+ });
+ return fullResponse ? resp : resp.data;
+ }
+ getStream(url, query, { prefix = this._prefix, ...rest } = {}) {
+ return this._requestMaker.sendStream({
+ url: prefix ? prefix + url : url,
+ method: 'GET',
+ query,
+ ...rest,
+ });
+ }
+ postStream(url, body, { prefix = this._prefix, ...rest } = {}) {
+ return this._requestMaker.sendStream({
+ url: prefix ? prefix + url : url,
+ method: 'POST',
+ body,
+ ...rest,
+ });
+ }
+}
+exports.default = TwitterApiBase;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client.subclient.d.ts b/node_modules/twitter-api-v2/dist/cjs/client.subclient.d.ts
new file mode 100644
index 0000000..e468a03
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client.subclient.d.ts
@@ -0,0 +1,7 @@
+import TwitterApiBase from './client.base';
+/**
+ * Base subclient for every v1 and v2 client.
+ */
+export default abstract class TwitterApiSubClient extends TwitterApiBase {
+ constructor(instance: TwitterApiBase);
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client.subclient.js b/node_modules/twitter-api-v2/dist/cjs/client.subclient.js
new file mode 100644
index 0000000..078ca02
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client.subclient.js
@@ -0,0 +1,18 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const client_base_1 = __importDefault(require("./client.base"));
+/**
+ * Base subclient for every v1 and v2 client.
+ */
+class TwitterApiSubClient extends client_base_1.default {
+ constructor(instance) {
+ if (!(instance instanceof client_base_1.default)) {
+ throw new Error('You must instance SubTwitterApi instance from existing TwitterApi instance.');
+ }
+ super(instance);
+ }
+}
+exports.default = TwitterApiSubClient;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/client/index.d.ts
new file mode 100644
index 0000000..5d7285b
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/index.d.ts
@@ -0,0 +1,22 @@
+import TwitterApiv1 from '../v1/client.v1';
+import TwitterApiv2 from '../v2/client.v2';
+import TwitterApiReadWrite from './readwrite';
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+export declare class TwitterApi extends TwitterApiReadWrite {
+ protected _v1?: TwitterApiv1;
+ protected _v2?: TwitterApiv2;
+ get v1(): TwitterApiv1;
+ get v2(): TwitterApiv2;
+ /**
+ * Get a client with read/write rights.
+ */
+ get readWrite(): TwitterApiReadWrite;
+ static getErrors(error: any): (import("../types").ErrorV1 | import("../types").ErrorV2)[];
+ /** Extract another image size than obtained in a `profile_image_url` or `profile_image_url_https` field of a user object. */
+ static getProfileImageInSize(profileImageUrl: string, size: 'normal' | 'bigger' | 'mini' | 'original'): string;
+}
+export { default as TwitterApiReadWrite } from './readwrite';
+export { default as TwitterApiReadOnly } from './readonly';
+export default TwitterApi;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/index.js b/node_modules/twitter-api-v2/dist/cjs/client/index.js
new file mode 100644
index 0000000..07bac3b
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/index.js
@@ -0,0 +1,70 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TwitterApiReadOnly = exports.TwitterApiReadWrite = exports.TwitterApi = void 0;
+const client_v1_1 = __importDefault(require("../v1/client.v1"));
+const client_v2_1 = __importDefault(require("../v2/client.v2"));
+const readwrite_1 = __importDefault(require("./readwrite"));
+// "Real" exported client for usage of TwitterApi.
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+class TwitterApi extends readwrite_1.default {
+ /* Direct access to subclients */
+ get v1() {
+ if (this._v1)
+ return this._v1;
+ return this._v1 = new client_v1_1.default(this);
+ }
+ get v2() {
+ if (this._v2)
+ return this._v2;
+ return this._v2 = new client_v2_1.default(this);
+ }
+ /**
+ * Get a client with read/write rights.
+ */
+ get readWrite() {
+ return this;
+ }
+ /* Static helpers */
+ static getErrors(error) {
+ var _a;
+ if (typeof error !== 'object')
+ return [];
+ if (!('data' in error))
+ return [];
+ return (_a = error.data.errors) !== null && _a !== void 0 ? _a : [];
+ }
+ /** Extract another image size than obtained in a `profile_image_url` or `profile_image_url_https` field of a user object. */
+ static getProfileImageInSize(profileImageUrl, size) {
+ const lastPart = profileImageUrl.split('/').pop();
+ const sizes = ['normal', 'bigger', 'mini'];
+ let originalUrl = profileImageUrl;
+ for (const availableSize of sizes) {
+ if (lastPart.includes(`_${availableSize}`)) {
+ originalUrl = profileImageUrl.replace(`_${availableSize}`, '');
+ break;
+ }
+ }
+ if (size === 'original') {
+ return originalUrl;
+ }
+ const extPos = originalUrl.lastIndexOf('.');
+ if (extPos !== -1) {
+ const ext = originalUrl.slice(extPos + 1);
+ return originalUrl.slice(0, extPos) + '_' + size + '.' + ext;
+ }
+ else {
+ return originalUrl + '_' + size;
+ }
+ }
+}
+exports.TwitterApi = TwitterApi;
+var readwrite_2 = require("./readwrite");
+Object.defineProperty(exports, "TwitterApiReadWrite", { enumerable: true, get: function () { return __importDefault(readwrite_2).default; } });
+var readonly_1 = require("./readonly");
+Object.defineProperty(exports, "TwitterApiReadOnly", { enumerable: true, get: function () { return __importDefault(readonly_1).default; } });
+exports.default = TwitterApi;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/readonly.d.ts b/node_modules/twitter-api-v2/dist/cjs/client/readonly.d.ts
new file mode 100644
index 0000000..c486627
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/readonly.d.ts
@@ -0,0 +1,157 @@
+import TwitterApi from '.';
+import TwitterApiBase from '../client.base';
+import { AccessOAuth2TokenArgs, AccessOAuth2TokenResult, BuildOAuth2RequestLinkArgs, IOAuth2RequestTokenResult, IParsedOAuth2TokenResult, LoginResult, RequestTokenArgs, Tweetv2SearchParams } from '../types';
+import TwitterApiv1ReadOnly from '../v1/client.v1.read';
+import TwitterApiv2ReadOnly from '../v2/client.v2.read';
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+export default class TwitterApiReadOnly extends TwitterApiBase {
+ protected _v1?: TwitterApiv1ReadOnly;
+ protected _v2?: TwitterApiv2ReadOnly;
+ get v1(): TwitterApiv1ReadOnly;
+ get v2(): TwitterApiv2ReadOnly;
+ /**
+ * Fetch and cache current user.
+ * This method can only be called with a OAuth 1.0a user authentication.
+ *
+ * You can use this method to test if authentication was successful.
+ * Next calls to this methods will use the cached user, unless `forceFetch: true` is given.
+ */
+ currentUser(forceFetch?: boolean): Promise;
+ /**
+ * Fetch and cache current user.
+ * This method can only be called with a OAuth 1.0a or OAuth2 user authentication.
+ *
+ * This can only be the slimest available `UserV2` object, with only id, name and username properties defined.
+ * To get a customized `UserV2Result`, use `.v2.me()`
+ *
+ * You can use this method to test if authentication was successful.
+ * Next calls to this methods will use the cached user, unless `forceFetch: true` is given.
+ *
+ * OAuth2 scopes: `tweet.read` & `users.read`
+ */
+ currentUserV2(forceFetch?: boolean): Promise;
+ search(what: string, options?: Partial): Promise;
+ /**
+ * Generate the OAuth request token link for user-based OAuth 1.0 auth.
+ *
+ * ```ts
+ * // Instantiate TwitterApi with consumer keys
+ * const client = new TwitterApi({ appKey: 'consumer_key', appSecret: 'consumer_secret' });
+ *
+ * const tokenRequest = await client.generateAuthLink('oob-or-your-callback-url');
+ * // redirect end-user to tokenRequest.url
+ *
+ * // Save tokenRequest.oauth_token_secret somewhere, it will be needed for next auth step.
+ * ```
+ */
+ generateAuthLink(oauth_callback?: string, { authAccessType, linkMode, forceLogin, screenName, }?: Partial): Promise<{
+ oauth_token: string;
+ oauth_token_secret: string;
+ oauth_callback_confirmed: "true";
+ url: string;
+ }>;
+ /**
+ * Obtain access to user-based OAuth 1.0 auth.
+ *
+ * After user is redirect from your callback, use obtained oauth_token and oauth_verifier to
+ * instantiate the new TwitterApi instance.
+ *
+ * ```ts
+ * // Use the saved oauth_token_secret associated to oauth_token returned by callback
+ * const requestClient = new TwitterApi({
+ * appKey: 'consumer_key',
+ * appSecret: 'consumer_secret',
+ * accessToken: 'oauth_token',
+ * accessSecret: 'oauth_token_secret'
+ * });
+ *
+ * // Use oauth_verifier obtained from callback request
+ * const { client: userClient } = await requestClient.login('oauth_verifier');
+ *
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * ```
+ */
+ login(oauth_verifier: string): Promise;
+ /**
+ * Enable application-only authentication.
+ *
+ * To make the request, instantiate TwitterApi with consumer and secret.
+ *
+ * ```ts
+ * const requestClient = new TwitterApi({ appKey: 'consumer', appSecret: 'secret' });
+ * const appClient = await requestClient.appLogin();
+ *
+ * // Use {appClient} to make requests
+ * ```
+ */
+ appLogin(): Promise;
+ /**
+ * Generate the OAuth request token link for user-based OAuth 2.0 auth.
+ *
+ * - **You can only use v2 API endpoints with this authentication method.**
+ * - **You need to specify which scope you want to have when you create your auth link. Make sure it matches your needs.**
+ *
+ * See https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token for details.
+ *
+ * ```ts
+ * // Instantiate TwitterApi with client ID
+ * const client = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * // Generate a link to callback URL that will gives a token with tweet+user read access
+ * const link = client.generateOAuth2AuthLink('your-callback-url', { scope: ['tweet.read', 'users.read'] });
+ *
+ * // Extract props from generate link
+ * const { url, state, codeVerifier } = link;
+ *
+ * // redirect end-user to url
+ * // Save `state` and `codeVerifier` somewhere, it will be needed for next auth step.
+ * ```
+ */
+ generateOAuth2AuthLink(redirectUri: string, options?: Partial): IOAuth2RequestTokenResult;
+ /**
+ * Obtain access to user-based OAuth 2.0 auth.
+ *
+ * After user is redirect from your callback, use obtained code to
+ * instantiate the new TwitterApi instance.
+ *
+ * You need to obtain `codeVerifier` from a call to `.generateOAuth2AuthLink`.
+ *
+ * ```ts
+ * // Use the saved codeVerifier associated to state (present in query string of callback)
+ * const requestClient = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * const { client: userClient, refreshToken } = await requestClient.loginWithOAuth2({
+ * code: 'codeFromQueryString',
+ * // the same URL given to generateOAuth2AuthLink
+ * redirectUri,
+ * // the verifier returned by generateOAuth2AuthLink
+ * codeVerifier,
+ * });
+ *
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * // {refreshToken} is defined if 'offline.access' is in scope.
+ * ```
+ */
+ loginWithOAuth2({ code, codeVerifier, redirectUri }: AccessOAuth2TokenArgs): Promise;
+ /**
+ * Obtain a new access token to user-based OAuth 2.0 auth from a refresh token.
+ *
+ * ```ts
+ * const requestClient = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * const { client: userClient } = await requestClient.refreshOAuth2Token('refreshToken');
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * ```
+ */
+ refreshOAuth2Token(refreshToken: string): Promise;
+ /**
+ * Revoke a single user-based OAuth 2.0 token.
+ *
+ * You must specify its source, access token (directly after login)
+ * or refresh token (if you've called `.refreshOAuth2Token` before).
+ */
+ revokeOAuth2Token(token: string, tokenType?: 'access_token' | 'refresh_token'): Promise;
+ protected parseOAuth2AccessTokenResult(result: AccessOAuth2TokenResult): IParsedOAuth2TokenResult;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/readonly.js b/node_modules/twitter-api-v2/dist/cjs/client/readonly.js
new file mode 100644
index 0000000..5f33dda
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/readonly.js
@@ -0,0 +1,305 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const _1 = __importDefault(require("."));
+const client_base_1 = __importDefault(require("../client.base"));
+const client_v1_read_1 = __importDefault(require("../v1/client.v1.read"));
+const client_v2_read_1 = __importDefault(require("../v2/client.v2.read"));
+const oauth2_helper_1 = require("../client-mixins/oauth2.helper");
+const request_param_helper_1 = __importDefault(require("../client-mixins/request-param.helper"));
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+class TwitterApiReadOnly extends client_base_1.default {
+ /* Direct access to subclients */
+ get v1() {
+ if (this._v1)
+ return this._v1;
+ return this._v1 = new client_v1_read_1.default(this);
+ }
+ get v2() {
+ if (this._v2)
+ return this._v2;
+ return this._v2 = new client_v2_read_1.default(this);
+ }
+ /**
+ * Fetch and cache current user.
+ * This method can only be called with a OAuth 1.0a user authentication.
+ *
+ * You can use this method to test if authentication was successful.
+ * Next calls to this methods will use the cached user, unless `forceFetch: true` is given.
+ */
+ async currentUser(forceFetch = false) {
+ return await this.getCurrentUserObject(forceFetch);
+ }
+ /**
+ * Fetch and cache current user.
+ * This method can only be called with a OAuth 1.0a or OAuth2 user authentication.
+ *
+ * This can only be the slimest available `UserV2` object, with only id, name and username properties defined.
+ * To get a customized `UserV2Result`, use `.v2.me()`
+ *
+ * You can use this method to test if authentication was successful.
+ * Next calls to this methods will use the cached user, unless `forceFetch: true` is given.
+ *
+ * OAuth2 scopes: `tweet.read` & `users.read`
+ */
+ async currentUserV2(forceFetch = false) {
+ return await this.getCurrentUserV2Object(forceFetch);
+ }
+ /* Shortcuts to endpoints */
+ search(what, options) {
+ return this.v2.search(what, options);
+ }
+ /* Authentication */
+ /**
+ * Generate the OAuth request token link for user-based OAuth 1.0 auth.
+ *
+ * ```ts
+ * // Instantiate TwitterApi with consumer keys
+ * const client = new TwitterApi({ appKey: 'consumer_key', appSecret: 'consumer_secret' });
+ *
+ * const tokenRequest = await client.generateAuthLink('oob-or-your-callback-url');
+ * // redirect end-user to tokenRequest.url
+ *
+ * // Save tokenRequest.oauth_token_secret somewhere, it will be needed for next auth step.
+ * ```
+ */
+ async generateAuthLink(oauth_callback = 'oob', { authAccessType, linkMode = 'authenticate', forceLogin, screenName, } = {}) {
+ const oauthResult = await this.post('https://api.twitter.com/oauth/request_token', { oauth_callback, x_auth_access_type: authAccessType });
+ let url = `https://api.twitter.com/oauth/${linkMode}?oauth_token=${encodeURIComponent(oauthResult.oauth_token)}`;
+ if (forceLogin !== undefined) {
+ url += `&force_login=${encodeURIComponent(forceLogin)}`;
+ }
+ if (screenName !== undefined) {
+ url += `&screen_name=${encodeURIComponent(screenName)}`;
+ }
+ if (this._requestMaker.hasPlugins()) {
+ this._requestMaker.applyPluginMethod('onOAuth1RequestToken', {
+ client: this._requestMaker,
+ url,
+ oauthResult,
+ });
+ }
+ return {
+ url,
+ ...oauthResult,
+ };
+ }
+ /**
+ * Obtain access to user-based OAuth 1.0 auth.
+ *
+ * After user is redirect from your callback, use obtained oauth_token and oauth_verifier to
+ * instantiate the new TwitterApi instance.
+ *
+ * ```ts
+ * // Use the saved oauth_token_secret associated to oauth_token returned by callback
+ * const requestClient = new TwitterApi({
+ * appKey: 'consumer_key',
+ * appSecret: 'consumer_secret',
+ * accessToken: 'oauth_token',
+ * accessSecret: 'oauth_token_secret'
+ * });
+ *
+ * // Use oauth_verifier obtained from callback request
+ * const { client: userClient } = await requestClient.login('oauth_verifier');
+ *
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * ```
+ */
+ async login(oauth_verifier) {
+ const tokens = this.getActiveTokens();
+ if (tokens.type !== 'oauth-1.0a')
+ throw new Error('You must setup TwitterApi instance with consumer keys to accept OAuth 1.0 login');
+ const oauth_result = await this.post('https://api.twitter.com/oauth/access_token', { oauth_token: tokens.accessToken, oauth_verifier });
+ const client = new _1.default({
+ appKey: tokens.appKey,
+ appSecret: tokens.appSecret,
+ accessToken: oauth_result.oauth_token,
+ accessSecret: oauth_result.oauth_token_secret,
+ }, this._requestMaker.clientSettings);
+ return {
+ accessToken: oauth_result.oauth_token,
+ accessSecret: oauth_result.oauth_token_secret,
+ userId: oauth_result.user_id,
+ screenName: oauth_result.screen_name,
+ client,
+ };
+ }
+ /**
+ * Enable application-only authentication.
+ *
+ * To make the request, instantiate TwitterApi with consumer and secret.
+ *
+ * ```ts
+ * const requestClient = new TwitterApi({ appKey: 'consumer', appSecret: 'secret' });
+ * const appClient = await requestClient.appLogin();
+ *
+ * // Use {appClient} to make requests
+ * ```
+ */
+ async appLogin() {
+ const tokens = this.getActiveTokens();
+ if (tokens.type !== 'oauth-1.0a')
+ throw new Error('You must setup TwitterApi instance with consumer keys to accept app-only login');
+ // Create a client with Basic authentication
+ const basicClient = new _1.default({ username: tokens.appKey, password: tokens.appSecret }, this._requestMaker.clientSettings);
+ const res = await basicClient.post('https://api.twitter.com/oauth2/token', { grant_type: 'client_credentials' });
+ // New object with Bearer token
+ return new _1.default(res.access_token, this._requestMaker.clientSettings);
+ }
+ /* OAuth 2 user authentication */
+ /**
+ * Generate the OAuth request token link for user-based OAuth 2.0 auth.
+ *
+ * - **You can only use v2 API endpoints with this authentication method.**
+ * - **You need to specify which scope you want to have when you create your auth link. Make sure it matches your needs.**
+ *
+ * See https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token for details.
+ *
+ * ```ts
+ * // Instantiate TwitterApi with client ID
+ * const client = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * // Generate a link to callback URL that will gives a token with tweet+user read access
+ * const link = client.generateOAuth2AuthLink('your-callback-url', { scope: ['tweet.read', 'users.read'] });
+ *
+ * // Extract props from generate link
+ * const { url, state, codeVerifier } = link;
+ *
+ * // redirect end-user to url
+ * // Save `state` and `codeVerifier` somewhere, it will be needed for next auth step.
+ * ```
+ */
+ generateOAuth2AuthLink(redirectUri, options = {}) {
+ var _a, _b;
+ if (!this._requestMaker.clientId) {
+ throw new Error('Twitter API instance is not initialized with client ID. You can find your client ID in Twitter Developer Portal. ' +
+ 'Please build an instance with: new TwitterApi({ clientId: \'\' })');
+ }
+ const state = (_a = options.state) !== null && _a !== void 0 ? _a : oauth2_helper_1.OAuth2Helper.generateRandomString(32);
+ const codeVerifier = oauth2_helper_1.OAuth2Helper.getCodeVerifier();
+ const codeChallenge = oauth2_helper_1.OAuth2Helper.getCodeChallengeFromVerifier(codeVerifier);
+ const rawScope = (_b = options.scope) !== null && _b !== void 0 ? _b : '';
+ const scope = Array.isArray(rawScope) ? rawScope.join(' ') : rawScope;
+ const url = new URL('https://twitter.com/i/oauth2/authorize');
+ const query = {
+ response_type: 'code',
+ client_id: this._requestMaker.clientId,
+ redirect_uri: redirectUri,
+ state,
+ code_challenge: codeChallenge,
+ code_challenge_method: 's256',
+ scope,
+ };
+ request_param_helper_1.default.addQueryParamsToUrl(url, query);
+ const result = {
+ url: url.toString(),
+ state,
+ codeVerifier,
+ codeChallenge,
+ };
+ if (this._requestMaker.hasPlugins()) {
+ this._requestMaker.applyPluginMethod('onOAuth2RequestToken', {
+ client: this._requestMaker,
+ result,
+ redirectUri,
+ });
+ }
+ return result;
+ }
+ /**
+ * Obtain access to user-based OAuth 2.0 auth.
+ *
+ * After user is redirect from your callback, use obtained code to
+ * instantiate the new TwitterApi instance.
+ *
+ * You need to obtain `codeVerifier` from a call to `.generateOAuth2AuthLink`.
+ *
+ * ```ts
+ * // Use the saved codeVerifier associated to state (present in query string of callback)
+ * const requestClient = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * const { client: userClient, refreshToken } = await requestClient.loginWithOAuth2({
+ * code: 'codeFromQueryString',
+ * // the same URL given to generateOAuth2AuthLink
+ * redirectUri,
+ * // the verifier returned by generateOAuth2AuthLink
+ * codeVerifier,
+ * });
+ *
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * // {refreshToken} is defined if 'offline.access' is in scope.
+ * ```
+ */
+ async loginWithOAuth2({ code, codeVerifier, redirectUri }) {
+ if (!this._requestMaker.clientId) {
+ throw new Error('Twitter API instance is not initialized with client ID. ' +
+ 'Please build an instance with: new TwitterApi({ clientId: \'\' })');
+ }
+ const accessTokenResult = await this.post('https://api.twitter.com/2/oauth2/token', {
+ code,
+ code_verifier: codeVerifier,
+ redirect_uri: redirectUri,
+ grant_type: 'authorization_code',
+ client_id: this._requestMaker.clientId,
+ client_secret: this._requestMaker.clientSecret,
+ });
+ return this.parseOAuth2AccessTokenResult(accessTokenResult);
+ }
+ /**
+ * Obtain a new access token to user-based OAuth 2.0 auth from a refresh token.
+ *
+ * ```ts
+ * const requestClient = new TwitterApi({ clientId: 'yourClientId' });
+ *
+ * const { client: userClient } = await requestClient.refreshOAuth2Token('refreshToken');
+ * // {userClient} is a valid {TwitterApi} object you can use for future requests
+ * ```
+ */
+ async refreshOAuth2Token(refreshToken) {
+ if (!this._requestMaker.clientId) {
+ throw new Error('Twitter API instance is not initialized with client ID. ' +
+ 'Please build an instance with: new TwitterApi({ clientId: \'\' })');
+ }
+ const accessTokenResult = await this.post('https://api.twitter.com/2/oauth2/token', {
+ refresh_token: refreshToken,
+ grant_type: 'refresh_token',
+ client_id: this._requestMaker.clientId,
+ client_secret: this._requestMaker.clientSecret,
+ });
+ return this.parseOAuth2AccessTokenResult(accessTokenResult);
+ }
+ /**
+ * Revoke a single user-based OAuth 2.0 token.
+ *
+ * You must specify its source, access token (directly after login)
+ * or refresh token (if you've called `.refreshOAuth2Token` before).
+ */
+ async revokeOAuth2Token(token, tokenType = 'access_token') {
+ if (!this._requestMaker.clientId) {
+ throw new Error('Twitter API instance is not initialized with client ID. ' +
+ 'Please build an instance with: new TwitterApi({ clientId: \'\' })');
+ }
+ return await this.post('https://api.twitter.com/2/oauth2/revoke', {
+ client_id: this._requestMaker.clientId,
+ client_secret: this._requestMaker.clientSecret,
+ token,
+ token_type_hint: tokenType,
+ });
+ }
+ parseOAuth2AccessTokenResult(result) {
+ const client = new _1.default(result.access_token, this._requestMaker.clientSettings);
+ const scope = result.scope.split(' ').filter(e => e);
+ return {
+ client,
+ expiresIn: result.expires_in,
+ accessToken: result.access_token,
+ scope,
+ refreshToken: result.refresh_token,
+ };
+ }
+}
+exports.default = TwitterApiReadOnly;
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/readwrite.d.ts b/node_modules/twitter-api-v2/dist/cjs/client/readwrite.d.ts
new file mode 100644
index 0000000..c2e35b8
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/readwrite.d.ts
@@ -0,0 +1,16 @@
+import TwitterApiv1ReadWrite from '../v1/client.v1.write';
+import TwitterApiv2ReadWrite from '../v2/client.v2.write';
+import TwitterApiReadOnly from './readonly';
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+export default class TwitterApiReadWrite extends TwitterApiReadOnly {
+ protected _v1?: TwitterApiv1ReadWrite;
+ protected _v2?: TwitterApiv2ReadWrite;
+ get v1(): TwitterApiv1ReadWrite;
+ get v2(): TwitterApiv2ReadWrite;
+ /**
+ * Get a client with read only rights.
+ */
+ get readOnly(): TwitterApiReadOnly;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/client/readwrite.js b/node_modules/twitter-api-v2/dist/cjs/client/readwrite.js
new file mode 100644
index 0000000..93efb16
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/client/readwrite.js
@@ -0,0 +1,31 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const client_v1_write_1 = __importDefault(require("../v1/client.v1.write"));
+const client_v2_write_1 = __importDefault(require("../v2/client.v2.write"));
+const readonly_1 = __importDefault(require("./readonly"));
+/**
+ * Twitter v1.1 and v2 API client.
+ */
+class TwitterApiReadWrite extends readonly_1.default {
+ /* Direct access to subclients */
+ get v1() {
+ if (this._v1)
+ return this._v1;
+ return this._v1 = new client_v1_write_1.default(this);
+ }
+ get v2() {
+ if (this._v2)
+ return this._v2;
+ return this._v2 = new client_v2_write_1.default(this);
+ }
+ /**
+ * Get a client with read only rights.
+ */
+ get readOnly() {
+ return this;
+ }
+}
+exports.default = TwitterApiReadWrite;
diff --git a/node_modules/twitter-api-v2/dist/cjs/globals.d.ts b/node_modules/twitter-api-v2/dist/cjs/globals.d.ts
new file mode 100644
index 0000000..dcb64a6
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/globals.d.ts
@@ -0,0 +1,5 @@
+export declare const API_V2_PREFIX = "https://api.twitter.com/2/";
+export declare const API_V2_LABS_PREFIX = "https://api.twitter.com/labs/2/";
+export declare const API_V1_1_PREFIX = "https://api.twitter.com/1.1/";
+export declare const API_V1_1_UPLOAD_PREFIX = "https://upload.twitter.com/1.1/";
+export declare const API_V1_1_STREAM_PREFIX = "https://stream.twitter.com/1.1/";
diff --git a/node_modules/twitter-api-v2/dist/cjs/globals.js b/node_modules/twitter-api-v2/dist/cjs/globals.js
new file mode 100644
index 0000000..84a51b4
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/globals.js
@@ -0,0 +1,8 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.API_V1_1_STREAM_PREFIX = exports.API_V1_1_UPLOAD_PREFIX = exports.API_V1_1_PREFIX = exports.API_V2_LABS_PREFIX = exports.API_V2_PREFIX = void 0;
+exports.API_V2_PREFIX = 'https://api.twitter.com/2/';
+exports.API_V2_LABS_PREFIX = 'https://api.twitter.com/labs/2/';
+exports.API_V1_1_PREFIX = 'https://api.twitter.com/1.1/';
+exports.API_V1_1_UPLOAD_PREFIX = 'https://upload.twitter.com/1.1/';
+exports.API_V1_1_STREAM_PREFIX = 'https://stream.twitter.com/1.1/';
diff --git a/node_modules/twitter-api-v2/dist/cjs/helpers.d.ts b/node_modules/twitter-api-v2/dist/cjs/helpers.d.ts
new file mode 100644
index 0000000..bbc3fa9
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/helpers.d.ts
@@ -0,0 +1,16 @@
+export interface SharedPromise {
+ value: T | undefined;
+ promise: Promise;
+}
+export declare function sharedPromise(getter: () => Promise): SharedPromise;
+export declare function arrayWrap(value: T | T[]): T[];
+export declare function trimUndefinedProperties(object: any): void;
+export declare function isTweetStreamV2ErrorPayload(payload: any): boolean;
+export declare function hasMultipleItems(item: string | string[]): boolean;
+export interface IDeprecationWarning {
+ instance: string;
+ method: string;
+ problem: string;
+ resolution: string;
+}
+export declare function safeDeprecationWarning(message: IDeprecationWarning): void;
diff --git a/node_modules/twitter-api-v2/dist/cjs/helpers.js b/node_modules/twitter-api-v2/dist/cjs/helpers.js
new file mode 100644
index 0000000..f0d84a0
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/helpers.js
@@ -0,0 +1,60 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.safeDeprecationWarning = exports.hasMultipleItems = exports.isTweetStreamV2ErrorPayload = exports.trimUndefinedProperties = exports.arrayWrap = exports.sharedPromise = void 0;
+const settings_1 = require("./settings");
+function sharedPromise(getter) {
+ const sharedPromise = {
+ value: undefined,
+ promise: getter().then(val => {
+ sharedPromise.value = val;
+ return val;
+ }),
+ };
+ return sharedPromise;
+}
+exports.sharedPromise = sharedPromise;
+function arrayWrap(value) {
+ if (Array.isArray(value)) {
+ return value;
+ }
+ return [value];
+}
+exports.arrayWrap = arrayWrap;
+function trimUndefinedProperties(object) {
+ // Delete undefined parameters
+ for (const parameter in object) {
+ if (object[parameter] === undefined)
+ delete object[parameter];
+ }
+}
+exports.trimUndefinedProperties = trimUndefinedProperties;
+function isTweetStreamV2ErrorPayload(payload) {
+ // Is error only if 'errors' is present and 'data' does not exists
+ return typeof payload === 'object'
+ && 'errors' in payload
+ && !('data' in payload);
+}
+exports.isTweetStreamV2ErrorPayload = isTweetStreamV2ErrorPayload;
+function hasMultipleItems(item) {
+ if (Array.isArray(item) && item.length > 1) {
+ return true;
+ }
+ return item.toString().includes(',');
+}
+exports.hasMultipleItems = hasMultipleItems;
+const deprecationWarningsCache = new Set();
+function safeDeprecationWarning(message) {
+ if (typeof console === 'undefined' || !console.warn || !settings_1.TwitterApiV2Settings.deprecationWarnings) {
+ return;
+ }
+ const hash = `${message.instance}-${message.method}-${message.problem}`;
+ if (deprecationWarningsCache.has(hash)) {
+ return;
+ }
+ const formattedMsg = `[twitter-api-v2] Deprecation warning: In ${message.instance}.${message.method}() call` +
+ `, ${message.problem}.\n${message.resolution}.`;
+ console.warn(formattedMsg);
+ console.warn('To disable this message, import variable TwitterApiV2Settings from twitter-api-v2 and set TwitterApiV2Settings.deprecationWarnings to false.');
+ deprecationWarningsCache.add(hash);
+}
+exports.safeDeprecationWarning = safeDeprecationWarning;
diff --git a/node_modules/twitter-api-v2/dist/cjs/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/index.d.ts
new file mode 100644
index 0000000..98a08f9
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/index.d.ts
@@ -0,0 +1,10 @@
+export { default as default } from './client';
+export * from './client';
+export * from './v1/client.v1';
+export * from './v2/client.v2';
+export * from './v2/includes.v2.helper';
+export * from './v2-labs/client.v2.labs';
+export * from './types';
+export * from './paginators';
+export * from './stream/TweetStream';
+export * from './settings';
diff --git a/node_modules/twitter-api-v2/dist/cjs/index.js b/node_modules/twitter-api-v2/dist/cjs/index.js
new file mode 100644
index 0000000..aed5f97
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/index.js
@@ -0,0 +1,31 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = void 0;
+var client_1 = require("./client");
+Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(client_1).default; } });
+__exportStar(require("./client"), exports);
+__exportStar(require("./v1/client.v1"), exports);
+__exportStar(require("./v2/client.v2"), exports);
+__exportStar(require("./v2/includes.v2.helper"), exports);
+__exportStar(require("./v2-labs/client.v2.labs"), exports);
+__exportStar(require("./types"), exports);
+__exportStar(require("./paginators"), exports);
+__exportStar(require("./stream/TweetStream"), exports);
+__exportStar(require("./settings"), exports);
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.d.ts
new file mode 100644
index 0000000..788d1bb
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.d.ts
@@ -0,0 +1,86 @@
+import { TwitterRateLimit, TwitterResponse } from '../types';
+import TwitterApiSubClient from '../client.subclient';
+export interface ITwitterPaginatorArgs {
+ realData: TApiResult;
+ rateLimit: TwitterRateLimit;
+ instance: TwitterApiSubClient;
+ queryParams: Partial;
+ sharedParams?: TParams;
+}
+/** TwitterPaginator: able to get consume data from initial request, then fetch next data sequentially. */
+export declare abstract class TwitterPaginator {
+ protected _realData: TApiResult;
+ protected _rateLimit: TwitterRateLimit;
+ protected _instance: TwitterApiSubClient;
+ protected _queryParams: Partial;
+ protected _maxResultsWhenFetchLast: number;
+ /** information unrelated to response data/query params that will be shared between paginator instances */
+ protected _sharedParams: TParams;
+ protected abstract _endpoint: string;
+ constructor({ realData, rateLimit, instance, queryParams, sharedParams }: ITwitterPaginatorArgs);
+ protected get _isRateLimitOk(): boolean;
+ protected makeRequest(queryParams: Partial): Promise>;
+ protected makeNewInstanceFromResult(result: TwitterResponse, queryParams: Partial): this;
+ protected getEndpoint(): string;
+ protected injectQueryParams(maxResults?: number): {
+ max_results?: number | undefined;
+ } & Partial;
+ protected abstract refreshInstanceFromResult(result: TwitterResponse, isNextPage: boolean): any;
+ protected abstract getNextQueryParams(maxResults?: number): Partial;
+ protected abstract getPageLengthFromRequest(result: TwitterResponse): number;
+ protected abstract isFetchLastOver(result: TwitterResponse): boolean;
+ protected abstract canFetchNextPage(result: TApiResult): boolean;
+ protected abstract getItemArray(): TItem[];
+ /**
+ * Next page.
+ */
+ next(maxResults?: number): Promise;
+ /**
+ * Next page, but store it in current instance.
+ */
+ fetchNext(maxResults?: number): Promise;
+ /**
+ * Fetch up to {count} items after current page,
+ * as long as rate limit is not hit and Twitter has some results
+ */
+ fetchLast(count?: number): Promise;
+ get rateLimit(): {
+ limit: number;
+ reset: number;
+ remaining: number;
+ };
+ /** Get raw data returned by Twitter API. */
+ get data(): TApiResult;
+ get done(): boolean;
+ /**
+ * Iterate over currently fetched items.
+ */
+ [Symbol.iterator](): Generator;
+ /**
+ * Iterate over items "indefinitely" (until rate limit is hit / they're no more items available)
+ * This will **mutate the current instance** and fill data, metas, etc. inside this instance.
+ *
+ * If you need to handle concurrent requests, or you need to rely on immutability, please use `.fetchAndIterate()` instead.
+ */
+ [Symbol.asyncIterator](): AsyncGenerator;
+ /**
+ * Iterate over items "indefinitely" without modifying the current instance (until rate limit is hit / they're no more items available)
+ *
+ * This will **NOT** mutate the current instance, meaning that current instance will not inherit from `includes` and `meta` (v2 API only).
+ * Use `Symbol.asyncIterator` (`for-await of`) to directly access items with current instance mutation.
+ */
+ fetchAndIterate(): AsyncGenerator<[TItem, this], void, undefined>;
+}
+/** PreviousableTwitterPaginator: a TwitterPaginator able to get consume data from both side, next and previous. */
+export declare abstract class PreviousableTwitterPaginator extends TwitterPaginator {
+ protected abstract getPreviousQueryParams(maxResults?: number): Partial;
+ /**
+ * Previous page (new tweets)
+ */
+ previous(maxResults?: number): Promise;
+ /**
+ * Previous page, but in current instance.
+ */
+ fetchPrevious(maxResults?: number): Promise;
+}
+export default TwitterPaginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.js b/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.js
new file mode 100644
index 0000000..2f458fe
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/TwitterPaginator.js
@@ -0,0 +1,173 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.PreviousableTwitterPaginator = exports.TwitterPaginator = void 0;
+/** TwitterPaginator: able to get consume data from initial request, then fetch next data sequentially. */
+class TwitterPaginator {
+ // noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected
+ constructor({ realData, rateLimit, instance, queryParams, sharedParams }) {
+ this._maxResultsWhenFetchLast = 100;
+ this._realData = realData;
+ this._rateLimit = rateLimit;
+ this._instance = instance;
+ this._queryParams = queryParams;
+ this._sharedParams = sharedParams;
+ }
+ get _isRateLimitOk() {
+ if (!this._rateLimit) {
+ return true;
+ }
+ const resetDate = this._rateLimit.reset * 1000;
+ if (resetDate < Date.now()) {
+ return true;
+ }
+ return this._rateLimit.remaining > 0;
+ }
+ makeRequest(queryParams) {
+ return this._instance.get(this.getEndpoint(), queryParams, { fullResponse: true, params: this._sharedParams });
+ }
+ makeNewInstanceFromResult(result, queryParams) {
+ // Construct a subclass
+ return new this.constructor({
+ realData: result.data,
+ rateLimit: result.rateLimit,
+ instance: this._instance,
+ queryParams,
+ sharedParams: this._sharedParams,
+ });
+ }
+ getEndpoint() {
+ return this._endpoint;
+ }
+ injectQueryParams(maxResults) {
+ return {
+ ...(maxResults ? { max_results: maxResults } : {}),
+ ...this._queryParams,
+ };
+ }
+ /* ---------------------- */
+ /* Real paginator methods */
+ /* ---------------------- */
+ /**
+ * Next page.
+ */
+ async next(maxResults) {
+ const queryParams = this.getNextQueryParams(maxResults);
+ const result = await this.makeRequest(queryParams);
+ return this.makeNewInstanceFromResult(result, queryParams);
+ }
+ /**
+ * Next page, but store it in current instance.
+ */
+ async fetchNext(maxResults) {
+ const queryParams = this.getNextQueryParams(maxResults);
+ const result = await this.makeRequest(queryParams);
+ // Await in case of async sub-methods
+ await this.refreshInstanceFromResult(result, true);
+ return this;
+ }
+ /**
+ * Fetch up to {count} items after current page,
+ * as long as rate limit is not hit and Twitter has some results
+ */
+ async fetchLast(count = Infinity) {
+ let queryParams = this.getNextQueryParams(this._maxResultsWhenFetchLast);
+ let resultCount = 0;
+ // Break at rate limit limit
+ while (resultCount < count && this._isRateLimitOk) {
+ const response = await this.makeRequest(queryParams);
+ await this.refreshInstanceFromResult(response, true);
+ resultCount += this.getPageLengthFromRequest(response);
+ if (this.isFetchLastOver(response)) {
+ break;
+ }
+ queryParams = this.getNextQueryParams(this._maxResultsWhenFetchLast);
+ }
+ return this;
+ }
+ get rateLimit() {
+ var _a;
+ return { ...(_a = this._rateLimit) !== null && _a !== void 0 ? _a : {} };
+ }
+ /** Get raw data returned by Twitter API. */
+ get data() {
+ return this._realData;
+ }
+ get done() {
+ return !this.canFetchNextPage(this._realData);
+ }
+ /**
+ * Iterate over currently fetched items.
+ */
+ *[Symbol.iterator]() {
+ yield* this.getItemArray();
+ }
+ /**
+ * Iterate over items "indefinitely" (until rate limit is hit / they're no more items available)
+ * This will **mutate the current instance** and fill data, metas, etc. inside this instance.
+ *
+ * If you need to handle concurrent requests, or you need to rely on immutability, please use `.fetchAndIterate()` instead.
+ */
+ async *[Symbol.asyncIterator]() {
+ yield* this.getItemArray();
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ let paginator = this;
+ let canFetchNextPage = this.canFetchNextPage(this._realData);
+ while (canFetchNextPage && this._isRateLimitOk && paginator.getItemArray().length > 0) {
+ const next = await paginator.next(this._maxResultsWhenFetchLast);
+ // Store data into current instance [needed to access includes and meta]
+ this.refreshInstanceFromResult({ data: next._realData, headers: {}, rateLimit: next._rateLimit }, true);
+ canFetchNextPage = this.canFetchNextPage(next._realData);
+ const items = next.getItemArray();
+ yield* items;
+ paginator = next;
+ }
+ }
+ /**
+ * Iterate over items "indefinitely" without modifying the current instance (until rate limit is hit / they're no more items available)
+ *
+ * This will **NOT** mutate the current instance, meaning that current instance will not inherit from `includes` and `meta` (v2 API only).
+ * Use `Symbol.asyncIterator` (`for-await of`) to directly access items with current instance mutation.
+ */
+ async *fetchAndIterate() {
+ for (const item of this.getItemArray()) {
+ yield [item, this];
+ }
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ let paginator = this;
+ let canFetchNextPage = this.canFetchNextPage(this._realData);
+ while (canFetchNextPage && this._isRateLimitOk && paginator.getItemArray().length > 0) {
+ const next = await paginator.next(this._maxResultsWhenFetchLast);
+ // Store data into current instance [needed to access includes and meta]
+ this.refreshInstanceFromResult({ data: next._realData, headers: {}, rateLimit: next._rateLimit }, true);
+ canFetchNextPage = this.canFetchNextPage(next._realData);
+ for (const item of next.getItemArray()) {
+ yield [item, next];
+ }
+ this._rateLimit = next._rateLimit;
+ paginator = next;
+ }
+ }
+}
+exports.TwitterPaginator = TwitterPaginator;
+/** PreviousableTwitterPaginator: a TwitterPaginator able to get consume data from both side, next and previous. */
+class PreviousableTwitterPaginator extends TwitterPaginator {
+ /**
+ * Previous page (new tweets)
+ */
+ async previous(maxResults) {
+ const queryParams = this.getPreviousQueryParams(maxResults);
+ const result = await this.makeRequest(queryParams);
+ return this.makeNewInstanceFromResult(result, queryParams);
+ }
+ /**
+ * Previous page, but in current instance.
+ */
+ async fetchPrevious(maxResults) {
+ const queryParams = this.getPreviousQueryParams(maxResults);
+ const result = await this.makeRequest(queryParams);
+ await this.refreshInstanceFromResult(result, false);
+ return this;
+ }
+}
+exports.PreviousableTwitterPaginator = PreviousableTwitterPaginator;
+exports.default = TwitterPaginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.d.ts
new file mode 100644
index 0000000..085f9d8
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.d.ts
@@ -0,0 +1,19 @@
+import type { GetDmListV1Args, ReceivedDMEventsV1, TReceivedDMEvent, TwitterResponse, ReceivedWelcomeDMCreateEventV1, WelcomeDirectMessageListV1Result } from '../types';
+import { CursoredV1Paginator } from './paginator.v1';
+export declare class DmEventsV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): import("../types").DirectMessageCreateV1[];
+ /**
+ * Events returned by paginator.
+ */
+ get events(): import("../types").DirectMessageCreateV1[];
+}
+export declare class WelcomeDmV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): ReceivedWelcomeDMCreateEventV1[];
+ get welcomeMessages(): ReceivedWelcomeDMCreateEventV1[];
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.js
new file mode 100644
index 0000000..d2803de
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v1.js
@@ -0,0 +1,55 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.WelcomeDmV1Paginator = exports.DmEventsV1Paginator = void 0;
+const paginator_v1_1 = require("./paginator.v1");
+class DmEventsV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'direct_messages/events/list.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.events.push(...result.events);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.events.length;
+ }
+ getItemArray() {
+ return this.events;
+ }
+ /**
+ * Events returned by paginator.
+ */
+ get events() {
+ return this._realData.events;
+ }
+}
+exports.DmEventsV1Paginator = DmEventsV1Paginator;
+class WelcomeDmV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'direct_messages/welcome_messages/list.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.welcome_messages.push(...result.welcome_messages);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.welcome_messages.length;
+ }
+ getItemArray() {
+ return this.welcomeMessages;
+ }
+ get welcomeMessages() {
+ return this._realData.welcome_messages;
+ }
+}
+exports.WelcomeDmV1Paginator = WelcomeDmV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.d.ts
new file mode 100644
index 0000000..60db343
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.d.ts
@@ -0,0 +1,23 @@
+import { TimelineV2Paginator } from './v2.paginator';
+import { DMEventV2, GetDMEventV2Params, GetDMEventV2Result } from '../types/v2/dm.v2.types';
+export declare abstract class DMTimelineV2Paginator extends TimelineV2Paginator {
+ protected getItemArray(): DMEventV2[];
+ /**
+ * Events returned by paginator.
+ */
+ get events(): DMEventV2[];
+ get meta(): import("../types/v2/shared.v2.types").PaginableCountMetaV2;
+}
+export declare class FullDMTimelineV2Paginator extends DMTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class OneToOneDMTimelineV2Paginator extends DMTimelineV2Paginator<{
+ participant_id: string;
+}> {
+ protected _endpoint: string;
+}
+export declare class ConversationDMTimelineV2Paginator extends DMTimelineV2Paginator<{
+ dm_conversation_id: string;
+}> {
+ protected _endpoint: string;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.js b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.js
new file mode 100644
index 0000000..9bb80a2
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/dm.paginator.v2.js
@@ -0,0 +1,41 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ConversationDMTimelineV2Paginator = exports.OneToOneDMTimelineV2Paginator = exports.FullDMTimelineV2Paginator = exports.DMTimelineV2Paginator = void 0;
+const v2_paginator_1 = require("./v2.paginator");
+class DMTimelineV2Paginator extends v2_paginator_1.TimelineV2Paginator {
+ getItemArray() {
+ return this.events;
+ }
+ /**
+ * Events returned by paginator.
+ */
+ get events() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+}
+exports.DMTimelineV2Paginator = DMTimelineV2Paginator;
+class FullDMTimelineV2Paginator extends DMTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'dm_events';
+ }
+}
+exports.FullDMTimelineV2Paginator = FullDMTimelineV2Paginator;
+class OneToOneDMTimelineV2Paginator extends DMTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'dm_conversations/with/:participant_id/dm_events';
+ }
+}
+exports.OneToOneDMTimelineV2Paginator = OneToOneDMTimelineV2Paginator;
+class ConversationDMTimelineV2Paginator extends DMTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'dm_conversations/:dm_conversation_id/dm_events';
+ }
+}
+exports.ConversationDMTimelineV2Paginator = ConversationDMTimelineV2Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.d.ts
new file mode 100644
index 0000000..4451e6e
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.d.ts
@@ -0,0 +1,23 @@
+import { CursoredV1Paginator } from './paginator.v1';
+import type { UserFollowerIdsV1Params, UserFollowerIdsV1Result, UserFollowerListV1Params, UserFollowerListV1Result, TwitterResponse, UserV1 } from '../types';
+export declare class UserFollowerListV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): UserV1[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV1[];
+}
+export declare class UserFollowerIdsV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected _maxResultsWhenFetchLast: number;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): string[];
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids(): string[];
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.js
new file mode 100644
index 0000000..b0f68b5
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/followers.paginator.v1.js
@@ -0,0 +1,59 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.UserFollowerIdsV1Paginator = exports.UserFollowerListV1Paginator = void 0;
+const paginator_v1_1 = require("./paginator.v1");
+class UserFollowerListV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'followers/list.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.users.push(...result.users);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.users.length;
+ }
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ return this._realData.users;
+ }
+}
+exports.UserFollowerListV1Paginator = UserFollowerListV1Paginator;
+class UserFollowerIdsV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'followers/ids.json';
+ this._maxResultsWhenFetchLast = 5000;
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.ids.push(...result.ids);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.ids.length;
+ }
+ getItemArray() {
+ return this.ids;
+ }
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids() {
+ return this._realData.ids;
+ }
+}
+exports.UserFollowerIdsV1Paginator = UserFollowerIdsV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.d.ts
new file mode 100644
index 0000000..9a3e35e
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.d.ts
@@ -0,0 +1,23 @@
+import { CursoredV1Paginator } from './paginator.v1';
+import type { UserFollowerIdsV1Params, UserFollowerIdsV1Result, UserFriendListV1Params, UserFriendListV1Result, UserV1, TwitterResponse } from '../types';
+export declare class UserFriendListV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): UserV1[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV1[];
+}
+export declare class UserFollowersIdsV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected _maxResultsWhenFetchLast: number;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): string[];
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids(): string[];
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.js
new file mode 100644
index 0000000..8874648
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/friends.paginator.v1.js
@@ -0,0 +1,59 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.UserFollowersIdsV1Paginator = exports.UserFriendListV1Paginator = void 0;
+const paginator_v1_1 = require("./paginator.v1");
+class UserFriendListV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'friends/list.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.users.push(...result.users);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.users.length;
+ }
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ return this._realData.users;
+ }
+}
+exports.UserFriendListV1Paginator = UserFriendListV1Paginator;
+class UserFollowersIdsV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'friends/ids.json';
+ this._maxResultsWhenFetchLast = 5000;
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.ids.push(...result.ids);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.ids.length;
+ }
+ getItemArray() {
+ return this.ids;
+ }
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids() {
+ return this._realData.ids;
+ }
+}
+exports.UserFollowersIdsV1Paginator = UserFollowersIdsV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/index.d.ts
new file mode 100644
index 0000000..6e2bbb2
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/index.d.ts
@@ -0,0 +1,11 @@
+export * from './tweet.paginator.v2';
+export * from './TwitterPaginator';
+export * from './dm.paginator.v1';
+export * from './mutes.paginator.v1';
+export * from './tweet.paginator.v1';
+export * from './user.paginator.v1';
+export * from './user.paginator.v2';
+export * from './list.paginator.v1';
+export * from './list.paginator.v2';
+export * from './friends.paginator.v1';
+export * from './followers.paginator.v1';
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/index.js b/node_modules/twitter-api-v2/dist/cjs/paginators/index.js
new file mode 100644
index 0000000..3f6f094
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/index.js
@@ -0,0 +1,27 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./tweet.paginator.v2"), exports);
+__exportStar(require("./TwitterPaginator"), exports);
+__exportStar(require("./dm.paginator.v1"), exports);
+__exportStar(require("./mutes.paginator.v1"), exports);
+__exportStar(require("./tweet.paginator.v1"), exports);
+__exportStar(require("./user.paginator.v1"), exports);
+__exportStar(require("./user.paginator.v2"), exports);
+__exportStar(require("./list.paginator.v1"), exports);
+__exportStar(require("./list.paginator.v2"), exports);
+__exportStar(require("./friends.paginator.v1"), exports);
+__exportStar(require("./followers.paginator.v1"), exports);
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.d.ts
new file mode 100644
index 0000000..7ab6bd3
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.d.ts
@@ -0,0 +1,36 @@
+import { DoubleEndedListsCursorV1Result, DoubleEndedUsersCursorV1Result, ListMembersV1Params, ListOwnershipsV1Params, ListV1, TwitterResponse, UserV1 } from '../types';
+import { CursoredV1Paginator } from './paginator.v1';
+declare abstract class ListListsV1Paginator extends CursoredV1Paginator {
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): ListV1[];
+ /**
+ * Lists returned by paginator.
+ */
+ get lists(): ListV1[];
+}
+export declare class ListMembershipsV1Paginator extends ListListsV1Paginator {
+ protected _endpoint: string;
+}
+export declare class ListOwnershipsV1Paginator extends ListListsV1Paginator {
+ protected _endpoint: string;
+}
+export declare class ListSubscriptionsV1Paginator extends ListListsV1Paginator {
+ protected _endpoint: string;
+}
+declare abstract class ListUsersV1Paginator extends CursoredV1Paginator {
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): UserV1[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV1[];
+}
+export declare class ListMembersV1Paginator extends ListUsersV1Paginator {
+ protected _endpoint: string;
+}
+export declare class ListSubscribersV1Paginator extends ListUsersV1Paginator {
+ protected _endpoint: string;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.js
new file mode 100644
index 0000000..906953a
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v1.js
@@ -0,0 +1,83 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ListSubscribersV1Paginator = exports.ListMembersV1Paginator = exports.ListSubscriptionsV1Paginator = exports.ListOwnershipsV1Paginator = exports.ListMembershipsV1Paginator = void 0;
+const paginator_v1_1 = require("./paginator.v1");
+class ListListsV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.lists.push(...result.lists);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.lists.length;
+ }
+ getItemArray() {
+ return this.lists;
+ }
+ /**
+ * Lists returned by paginator.
+ */
+ get lists() {
+ return this._realData.lists;
+ }
+}
+class ListMembershipsV1Paginator extends ListListsV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/memberships.json';
+ }
+}
+exports.ListMembershipsV1Paginator = ListMembershipsV1Paginator;
+class ListOwnershipsV1Paginator extends ListListsV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/ownerships.json';
+ }
+}
+exports.ListOwnershipsV1Paginator = ListOwnershipsV1Paginator;
+class ListSubscriptionsV1Paginator extends ListListsV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/subscriptions.json';
+ }
+}
+exports.ListSubscriptionsV1Paginator = ListSubscriptionsV1Paginator;
+class ListUsersV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.users.push(...result.users);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.users.length;
+ }
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ return this._realData.users;
+ }
+}
+class ListMembersV1Paginator extends ListUsersV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/members.json';
+ }
+}
+exports.ListMembersV1Paginator = ListMembersV1Paginator;
+class ListSubscribersV1Paginator extends ListUsersV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/subscribers.json';
+ }
+}
+exports.ListSubscribersV1Paginator = ListSubscribersV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.d.ts
new file mode 100644
index 0000000..06ccf00
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.d.ts
@@ -0,0 +1,26 @@
+import type { GetListTimelineV2Params, ListTimelineV2Result, ListV2 } from '../types';
+import { TimelineV2Paginator } from './v2.paginator';
+declare abstract class ListTimelineV2Paginator extends TimelineV2Paginator {
+ protected getItemArray(): ListV2[];
+ /**
+ * Lists returned by paginator.
+ */
+ get lists(): ListV2[];
+ get meta(): TResult["meta"];
+}
+export declare class UserOwnedListsV2Paginator extends ListTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserListMembershipsV2Paginator extends ListTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserListFollowedV2Paginator extends ListTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.js b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.js
new file mode 100644
index 0000000..1c50202
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/list.paginator.v2.js
@@ -0,0 +1,40 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.UserListFollowedV2Paginator = exports.UserListMembershipsV2Paginator = exports.UserOwnedListsV2Paginator = void 0;
+const v2_paginator_1 = require("./v2.paginator");
+class ListTimelineV2Paginator extends v2_paginator_1.TimelineV2Paginator {
+ getItemArray() {
+ return this.lists;
+ }
+ /**
+ * Lists returned by paginator.
+ */
+ get lists() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+}
+class UserOwnedListsV2Paginator extends ListTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/owned_lists';
+ }
+}
+exports.UserOwnedListsV2Paginator = UserOwnedListsV2Paginator;
+class UserListMembershipsV2Paginator extends ListTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/list_memberships';
+ }
+}
+exports.UserListMembershipsV2Paginator = UserListMembershipsV2Paginator;
+class UserListFollowedV2Paginator extends ListTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/followed_lists';
+ }
+}
+exports.UserListFollowedV2Paginator = UserListFollowedV2Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.d.ts
new file mode 100644
index 0000000..f54f937
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.d.ts
@@ -0,0 +1,23 @@
+import { CursoredV1Paginator } from './paginator.v1';
+import type { MuteUserIdsV1Params, MuteUserIdsV1Result, MuteUserListV1Params, MuteUserListV1Result, TwitterResponse, UserV1 } from '../types';
+export declare class MuteUserListV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): UserV1[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV1[];
+}
+export declare class MuteUserIdsV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected _maxResultsWhenFetchLast: number;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): string[];
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids(): string[];
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.js
new file mode 100644
index 0000000..00e09f1
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/mutes.paginator.v1.js
@@ -0,0 +1,59 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MuteUserIdsV1Paginator = exports.MuteUserListV1Paginator = void 0;
+const paginator_v1_1 = require("./paginator.v1");
+class MuteUserListV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'mutes/users/list.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.users.push(...result.users);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.users.length;
+ }
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ return this._realData.users;
+ }
+}
+exports.MuteUserListV1Paginator = MuteUserListV1Paginator;
+class MuteUserIdsV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'mutes/users/ids.json';
+ this._maxResultsWhenFetchLast = 5000;
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.ids.push(...result.ids);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.ids.length;
+ }
+ getItemArray() {
+ return this.ids;
+ }
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids() {
+ return this._realData.ids;
+ }
+}
+exports.MuteUserIdsV1Paginator = MuteUserIdsV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.d.ts
new file mode 100644
index 0000000..fc55abb
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.d.ts
@@ -0,0 +1,13 @@
+import { TwitterResponse } from '../types';
+import TwitterPaginator from './TwitterPaginator';
+export declare abstract class CursoredV1Paginator extends TwitterPaginator {
+ protected getNextQueryParams(maxResults?: number): Partial;
+ protected isFetchLastOver(result: TwitterResponse): boolean;
+ protected canFetchNextPage(result: TApiResult): boolean;
+ private isNextCursorInvalid;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.js
new file mode 100644
index 0000000..fc5e7e8
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/paginator.v1.js
@@ -0,0 +1,33 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.CursoredV1Paginator = void 0;
+const TwitterPaginator_1 = __importDefault(require("./TwitterPaginator"));
+class CursoredV1Paginator extends TwitterPaginator_1.default {
+ getNextQueryParams(maxResults) {
+ var _a;
+ return {
+ ...this._queryParams,
+ cursor: (_a = this._realData.next_cursor_str) !== null && _a !== void 0 ? _a : this._realData.next_cursor,
+ ...(maxResults ? { count: maxResults } : {}),
+ };
+ }
+ isFetchLastOver(result) {
+ // If we cant fetch next page
+ return !this.canFetchNextPage(result.data);
+ }
+ canFetchNextPage(result) {
+ // If one of cursor is valid
+ return !this.isNextCursorInvalid(result.next_cursor) || !this.isNextCursorInvalid(result.next_cursor_str);
+ }
+ isNextCursorInvalid(value) {
+ return value === undefined
+ || value === 0
+ || value === -1
+ || value === '0'
+ || value === '-1';
+ }
+}
+exports.CursoredV1Paginator = CursoredV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.d.ts
new file mode 100644
index 0000000..3172df6
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.d.ts
@@ -0,0 +1,37 @@
+import TwitterPaginator from './TwitterPaginator';
+import { TwitterResponse, TweetV1, TweetV1TimelineResult, TweetV1TimelineParams, TweetV1UserTimelineParams, ListStatusesV1Params } from '../types';
+/** A generic TwitterPaginator able to consume TweetV1 timelines. */
+declare abstract class TweetTimelineV1Paginator extends TwitterPaginator {
+ protected hasFinishedFetch: boolean;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getNextQueryParams(maxResults?: number): {
+ max_results?: number | undefined;
+ } & Partial & {
+ max_id: string;
+ };
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected isFetchLastOver(result: TwitterResponse): boolean;
+ protected canFetchNextPage(result: TResult): boolean;
+ protected getItemArray(): TResult;
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets(): TResult;
+ get done(): boolean;
+}
+export declare class HomeTimelineV1Paginator extends TweetTimelineV1Paginator {
+ protected _endpoint: string;
+}
+export declare class MentionTimelineV1Paginator extends TweetTimelineV1Paginator {
+ protected _endpoint: string;
+}
+export declare class UserTimelineV1Paginator extends TweetTimelineV1Paginator {
+ protected _endpoint: string;
+}
+export declare class ListTimelineV1Paginator extends TweetTimelineV1Paginator {
+ protected _endpoint: string;
+}
+export declare class UserFavoritesV1Paginator extends TweetTimelineV1Paginator {
+ protected _endpoint: string;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.js
new file mode 100644
index 0000000..ba24fc7
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v1.js
@@ -0,0 +1,92 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.UserFavoritesV1Paginator = exports.ListTimelineV1Paginator = exports.UserTimelineV1Paginator = exports.MentionTimelineV1Paginator = exports.HomeTimelineV1Paginator = void 0;
+const TwitterPaginator_1 = __importDefault(require("./TwitterPaginator"));
+/** A generic TwitterPaginator able to consume TweetV1 timelines. */
+class TweetTimelineV1Paginator extends TwitterPaginator_1.default {
+ constructor() {
+ super(...arguments);
+ this.hasFinishedFetch = false;
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.push(...result);
+ // HINT: This is an approximation, as "end" of pagination cannot be safely determined without cursors.
+ this.hasFinishedFetch = result.length === 0;
+ }
+ }
+ getNextQueryParams(maxResults) {
+ const latestId = BigInt(this._realData[this._realData.length - 1].id_str);
+ return {
+ ...this.injectQueryParams(maxResults),
+ max_id: (latestId - BigInt(1)).toString(),
+ };
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.length;
+ }
+ isFetchLastOver(result) {
+ return !result.data.length;
+ }
+ canFetchNextPage(result) {
+ return result.length > 0;
+ }
+ getItemArray() {
+ return this.tweets;
+ }
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets() {
+ return this._realData;
+ }
+ get done() {
+ return super.done || this.hasFinishedFetch;
+ }
+}
+// Timelines
+// Home
+class HomeTimelineV1Paginator extends TweetTimelineV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'statuses/home_timeline.json';
+ }
+}
+exports.HomeTimelineV1Paginator = HomeTimelineV1Paginator;
+// Mention
+class MentionTimelineV1Paginator extends TweetTimelineV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'statuses/mentions_timeline.json';
+ }
+}
+exports.MentionTimelineV1Paginator = MentionTimelineV1Paginator;
+// User
+class UserTimelineV1Paginator extends TweetTimelineV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'statuses/user_timeline.json';
+ }
+}
+exports.UserTimelineV1Paginator = UserTimelineV1Paginator;
+// Lists
+class ListTimelineV1Paginator extends TweetTimelineV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/statuses.json';
+ }
+}
+exports.ListTimelineV1Paginator = ListTimelineV1Paginator;
+// Favorites
+class UserFavoritesV1Paginator extends TweetTimelineV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'favorites/list.json';
+ }
+}
+exports.UserFavoritesV1Paginator = UserFavoritesV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.d.ts
new file mode 100644
index 0000000..d0b4f6c
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.d.ts
@@ -0,0 +1,74 @@
+import { Tweetv2SearchParams, Tweetv2SearchResult, TwitterResponse, TweetV2, Tweetv2TimelineResult, TweetV2TimelineParams, TweetV2PaginableTimelineResult, TweetV2UserTimelineParams, Tweetv2ListResult, TweetV2PaginableListParams, TweetV2PaginableTimelineParams, TweetV2HomeTimelineParams } from '../types';
+import { TimelineV2Paginator, TwitterV2Paginator } from './v2.paginator';
+/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines with since_id, until_id and next_token (when available). */
+declare abstract class TweetTimelineV2Paginator extends TwitterV2Paginator {
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: boolean): void;
+ protected getNextQueryParams(maxResults?: number): Partial;
+ protected getPreviousQueryParams(maxResults?: number): Partial;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected isFetchLastOver(result: TwitterResponse): boolean;
+ protected canFetchNextPage(result: TResult): boolean;
+ protected getItemArray(): TweetV2[];
+ protected dateStringToSnowflakeId(dateStr: string): string;
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets(): TweetV2[];
+ get meta(): TResult["meta"];
+}
+/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines with pagination_tokens. */
+declare abstract class TweetPaginableTimelineV2Paginator extends TimelineV2Paginator {
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: boolean): void;
+ protected getItemArray(): TweetV2[];
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets(): TweetV2[];
+ get meta(): TResult["meta"];
+}
+export declare class TweetSearchRecentV2Paginator extends TweetTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetSearchAllV2Paginator extends TweetTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class QuotedTweetsTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetHomeTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ protected _endpoint: string;
+}
+declare type TUserTimelinePaginatorShared = {
+ id: string;
+};
+export declare class TweetUserTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetUserMentionTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetBookmarksTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ protected _endpoint: string;
+}
+/** A generic TwitterPaginator able to consume TweetV2 timelines. */
+declare abstract class TweetListV2Paginator extends TimelineV2Paginator {
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets(): TweetV2[];
+ get meta(): TResult["meta"];
+ protected getItemArray(): TweetV2[];
+}
+export declare class TweetV2UserLikedTweetsPaginator extends TweetListV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetV2ListTweetsPaginator extends TweetListV2Paginator {
+ protected _endpoint: string;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.js b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.js
new file mode 100644
index 0000000..41fc469
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/tweet.paginator.v2.js
@@ -0,0 +1,205 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TweetV2ListTweetsPaginator = exports.TweetV2UserLikedTweetsPaginator = exports.TweetBookmarksTimelineV2Paginator = exports.TweetUserMentionTimelineV2Paginator = exports.TweetUserTimelineV2Paginator = exports.TweetHomeTimelineV2Paginator = exports.QuotedTweetsTimelineV2Paginator = exports.TweetSearchAllV2Paginator = exports.TweetSearchRecentV2Paginator = void 0;
+const v2_paginator_1 = require("./v2.paginator");
+/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines with since_id, until_id and next_token (when available). */
+class TweetTimelineV2Paginator extends v2_paginator_1.TwitterV2Paginator {
+ refreshInstanceFromResult(response, isNextPage) {
+ var _a;
+ const result = response.data;
+ const resultData = (_a = result.data) !== null && _a !== void 0 ? _a : [];
+ this._rateLimit = response.rateLimit;
+ if (!this._realData.data) {
+ this._realData.data = [];
+ }
+ if (isNextPage) {
+ this._realData.meta.oldest_id = result.meta.oldest_id;
+ this._realData.meta.result_count += result.meta.result_count;
+ this._realData.meta.next_token = result.meta.next_token;
+ this._realData.data.push(...resultData);
+ }
+ else {
+ this._realData.meta.newest_id = result.meta.newest_id;
+ this._realData.meta.result_count += result.meta.result_count;
+ this._realData.data.unshift(...resultData);
+ }
+ this.updateIncludes(result);
+ }
+ getNextQueryParams(maxResults) {
+ this.assertUsable();
+ const params = { ...this.injectQueryParams(maxResults) };
+ if (this._realData.meta.next_token) {
+ params.next_token = this._realData.meta.next_token;
+ }
+ else {
+ if (params.start_time) {
+ // until_id and start_time are forbidden together for some reason, so convert start_time to a since_id.
+ params.since_id = this.dateStringToSnowflakeId(params.start_time);
+ delete params.start_time;
+ }
+ if (params.end_time) {
+ // until_id overrides end_time, so delete it
+ delete params.end_time;
+ }
+ params.until_id = this._realData.meta.oldest_id;
+ }
+ return params;
+ }
+ getPreviousQueryParams(maxResults) {
+ this.assertUsable();
+ return {
+ ...this.injectQueryParams(maxResults),
+ since_id: this._realData.meta.newest_id,
+ };
+ }
+ getPageLengthFromRequest(result) {
+ var _a, _b;
+ return (_b = (_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
+ }
+ isFetchLastOver(result) {
+ var _a;
+ return !((_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) || !this.canFetchNextPage(result.data);
+ }
+ canFetchNextPage(result) {
+ return !!result.meta.next_token;
+ }
+ getItemArray() {
+ return this.tweets;
+ }
+ dateStringToSnowflakeId(dateStr) {
+ const TWITTER_START_EPOCH = BigInt('1288834974657');
+ const date = new Date(dateStr);
+ if (isNaN(date.valueOf())) {
+ throw new Error('Unable to convert start_time/end_time to a valid date. A ISO 8601 DateTime is excepted, please check your input.');
+ }
+ const dateTimestamp = BigInt(date.valueOf());
+ return ((dateTimestamp - TWITTER_START_EPOCH) << BigInt('22')).toString();
+ }
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+}
+/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines with pagination_tokens. */
+class TweetPaginableTimelineV2Paginator extends v2_paginator_1.TimelineV2Paginator {
+ refreshInstanceFromResult(response, isNextPage) {
+ super.refreshInstanceFromResult(response, isNextPage);
+ const result = response.data;
+ if (isNextPage) {
+ this._realData.meta.oldest_id = result.meta.oldest_id;
+ }
+ else {
+ this._realData.meta.newest_id = result.meta.newest_id;
+ }
+ }
+ getItemArray() {
+ return this.tweets;
+ }
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+}
+// ----------------
+// - Tweet search -
+// ----------------
+class TweetSearchRecentV2Paginator extends TweetTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'tweets/search/recent';
+ }
+}
+exports.TweetSearchRecentV2Paginator = TweetSearchRecentV2Paginator;
+class TweetSearchAllV2Paginator extends TweetTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'tweets/search/all';
+ }
+}
+exports.TweetSearchAllV2Paginator = TweetSearchAllV2Paginator;
+class QuotedTweetsTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'tweets/:id/quote_tweets';
+ }
+}
+exports.QuotedTweetsTimelineV2Paginator = QuotedTweetsTimelineV2Paginator;
+// -----------------
+// - Home timeline -
+// -----------------
+class TweetHomeTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/timelines/reverse_chronological';
+ }
+}
+exports.TweetHomeTimelineV2Paginator = TweetHomeTimelineV2Paginator;
+class TweetUserTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/tweets';
+ }
+}
+exports.TweetUserTimelineV2Paginator = TweetUserTimelineV2Paginator;
+class TweetUserMentionTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/mentions';
+ }
+}
+exports.TweetUserMentionTimelineV2Paginator = TweetUserMentionTimelineV2Paginator;
+// -------------
+// - Bookmarks -
+// -------------
+class TweetBookmarksTimelineV2Paginator extends TweetPaginableTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/bookmarks';
+ }
+}
+exports.TweetBookmarksTimelineV2Paginator = TweetBookmarksTimelineV2Paginator;
+// ---------------------------------------------------------------------------------
+// - Tweet lists (consume tweets with pagination tokens instead of since/until id) -
+// ---------------------------------------------------------------------------------
+/** A generic TwitterPaginator able to consume TweetV2 timelines. */
+class TweetListV2Paginator extends v2_paginator_1.TimelineV2Paginator {
+ /**
+ * Tweets returned by paginator.
+ */
+ get tweets() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+ getItemArray() {
+ return this.tweets;
+ }
+}
+class TweetV2UserLikedTweetsPaginator extends TweetListV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/liked_tweets';
+ }
+}
+exports.TweetV2UserLikedTweetsPaginator = TweetV2UserLikedTweetsPaginator;
+class TweetV2ListTweetsPaginator extends TweetListV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/:id/tweets';
+ }
+}
+exports.TweetV2ListTweetsPaginator = TweetV2ListTweetsPaginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.d.ts
new file mode 100644
index 0000000..4bcd0ff
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.d.ts
@@ -0,0 +1,37 @@
+import TwitterPaginator from './TwitterPaginator';
+import { FriendshipsIncomingV1Params, FriendshipsIncomingV1Result, TwitterResponse, UserSearchV1Params, UserV1 } from '../types';
+import { CursoredV1Paginator } from './paginator.v1';
+/** A generic TwitterPaginator able to consume TweetV1 timelines. */
+export declare class UserSearchV1Paginator extends TwitterPaginator {
+ _endpoint: string;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getNextQueryParams(maxResults?: number): {
+ count?: number | undefined;
+ page: number;
+ q?: string | undefined;
+ include_entities?: boolean | undefined;
+ tweet_mode?: "extended" | undefined;
+ };
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected isFetchLastOver(result: TwitterResponse): boolean;
+ protected canFetchNextPage(result: UserV1[]): boolean;
+ protected getItemArray(): UserV1[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV1[];
+}
+export declare class FriendshipsIncomingV1Paginator extends CursoredV1Paginator {
+ protected _endpoint: string;
+ protected _maxResultsWhenFetchLast: number;
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: true): void;
+ protected getPageLengthFromRequest(result: TwitterResponse): number;
+ protected getItemArray(): string[];
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids(): string[];
+}
+export declare class FriendshipsOutgoingV1Paginator extends FriendshipsIncomingV1Paginator {
+ protected _endpoint: string;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.js b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.js
new file mode 100644
index 0000000..39fb670
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v1.js
@@ -0,0 +1,85 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.FriendshipsOutgoingV1Paginator = exports.FriendshipsIncomingV1Paginator = exports.UserSearchV1Paginator = void 0;
+const TwitterPaginator_1 = __importDefault(require("./TwitterPaginator"));
+const paginator_v1_1 = require("./paginator.v1");
+/** A generic TwitterPaginator able to consume TweetV1 timelines. */
+class UserSearchV1Paginator extends TwitterPaginator_1.default {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/search.json';
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.push(...result);
+ }
+ }
+ getNextQueryParams(maxResults) {
+ var _a;
+ const previousPage = Number((_a = this._queryParams.page) !== null && _a !== void 0 ? _a : '1');
+ return {
+ ...this._queryParams,
+ page: previousPage + 1,
+ ...maxResults ? { count: maxResults } : {},
+ };
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.length;
+ }
+ isFetchLastOver(result) {
+ return !result.data.length;
+ }
+ canFetchNextPage(result) {
+ return result.length > 0;
+ }
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ return this._realData;
+ }
+}
+exports.UserSearchV1Paginator = UserSearchV1Paginator;
+class FriendshipsIncomingV1Paginator extends paginator_v1_1.CursoredV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'friendships/incoming.json';
+ this._maxResultsWhenFetchLast = 5000;
+ }
+ refreshInstanceFromResult(response, isNextPage) {
+ const result = response.data;
+ this._rateLimit = response.rateLimit;
+ if (isNextPage) {
+ this._realData.ids.push(...result.ids);
+ this._realData.next_cursor = result.next_cursor;
+ }
+ }
+ getPageLengthFromRequest(result) {
+ return result.data.ids.length;
+ }
+ getItemArray() {
+ return this.ids;
+ }
+ /**
+ * Users IDs returned by paginator.
+ */
+ get ids() {
+ return this._realData.ids;
+ }
+}
+exports.FriendshipsIncomingV1Paginator = FriendshipsIncomingV1Paginator;
+class FriendshipsOutgoingV1Paginator extends FriendshipsIncomingV1Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'friendships/outgoing.json';
+ }
+}
+exports.FriendshipsOutgoingV1Paginator = FriendshipsOutgoingV1Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.d.ts
new file mode 100644
index 0000000..ba1cd0e
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.d.ts
@@ -0,0 +1,52 @@
+import { UserV2, UserV2TimelineParams, UserV2TimelineResult } from '../types';
+import { TimelineV2Paginator } from './v2.paginator';
+/** A generic PreviousableTwitterPaginator able to consume UserV2 timelines. */
+declare abstract class UserTimelineV2Paginator extends TimelineV2Paginator {
+ protected getItemArray(): UserV2[];
+ /**
+ * Users returned by paginator.
+ */
+ get users(): UserV2[];
+ get meta(): TResult["meta"];
+}
+export declare class UserBlockingUsersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserMutingUsersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserFollowersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserFollowingV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserListMembersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class UserListFollowersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetLikingUsersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export declare class TweetRetweetersUsersV2Paginator extends UserTimelineV2Paginator {
+ protected _endpoint: string;
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.js b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.js
new file mode 100644
index 0000000..1cd5457
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/user.paginator.v2.js
@@ -0,0 +1,76 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TweetRetweetersUsersV2Paginator = exports.TweetLikingUsersV2Paginator = exports.UserListFollowersV2Paginator = exports.UserListMembersV2Paginator = exports.UserFollowingV2Paginator = exports.UserFollowersV2Paginator = exports.UserMutingUsersV2Paginator = exports.UserBlockingUsersV2Paginator = void 0;
+const v2_paginator_1 = require("./v2.paginator");
+/** A generic PreviousableTwitterPaginator able to consume UserV2 timelines. */
+class UserTimelineV2Paginator extends v2_paginator_1.TimelineV2Paginator {
+ getItemArray() {
+ return this.users;
+ }
+ /**
+ * Users returned by paginator.
+ */
+ get users() {
+ var _a;
+ return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
+ }
+ get meta() {
+ return super.meta;
+ }
+}
+class UserBlockingUsersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/blocking';
+ }
+}
+exports.UserBlockingUsersV2Paginator = UserBlockingUsersV2Paginator;
+class UserMutingUsersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/muting';
+ }
+}
+exports.UserMutingUsersV2Paginator = UserMutingUsersV2Paginator;
+class UserFollowersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/followers';
+ }
+}
+exports.UserFollowersV2Paginator = UserFollowersV2Paginator;
+class UserFollowingV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'users/:id/following';
+ }
+}
+exports.UserFollowingV2Paginator = UserFollowingV2Paginator;
+class UserListMembersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/:id/members';
+ }
+}
+exports.UserListMembersV2Paginator = UserListMembersV2Paginator;
+class UserListFollowersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'lists/:id/followers';
+ }
+}
+exports.UserListFollowersV2Paginator = UserListFollowersV2Paginator;
+class TweetLikingUsersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'tweets/:id/liking_users';
+ }
+}
+exports.TweetLikingUsersV2Paginator = TweetLikingUsersV2Paginator;
+class TweetRetweetersUsersV2Paginator extends UserTimelineV2Paginator {
+ constructor() {
+ super(...arguments);
+ this._endpoint = 'tweets/:id/retweeted_by';
+ }
+}
+exports.TweetRetweetersUsersV2Paginator = TweetRetweetersUsersV2Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.d.ts b/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.d.ts
new file mode 100644
index 0000000..1cdc52b
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.d.ts
@@ -0,0 +1,36 @@
+import type { TwitterResponse } from '../types';
+import type { DataMetaAndIncludeV2 } from '../types/v2/shared.v2.types';
+import { TwitterV2IncludesHelper } from '../v2/includes.v2.helper';
+import { PreviousableTwitterPaginator } from './TwitterPaginator';
+/** A generic PreviousableTwitterPaginator with common v2 helper methods. */
+export declare abstract class TwitterV2Paginator, TParams extends object, TItem, TShared = any> extends PreviousableTwitterPaginator {
+ protected _includesInstance?: TwitterV2IncludesHelper;
+ protected updateIncludes(data: TResult): void;
+ /** Throw if the current paginator is not usable. */
+ protected assertUsable(): void;
+ get meta(): any;
+ get includes(): TwitterV2IncludesHelper;
+ get errors(): import("../types").InlineErrorV2[];
+ /** `true` if this paginator only contains error payload and no metadata found to consume data. */
+ get unusable(): boolean;
+}
+/** A generic TwitterV2Paginator able to consume v2 timelines that use max_results and pagination tokens. */
+export declare abstract class TimelineV2Paginator, TParams extends {
+ max_results?: number;
+ pagination_token?: string;
+}, TItem, TShared = any> extends TwitterV2Paginator {
+ protected refreshInstanceFromResult(response: TwitterResponse, isNextPage: boolean): void;
+ protected getNextQueryParams(maxResults?: number): {
+ max_results?: number | undefined;
+ } & Partial & {
+ pagination_token: any;
+ };
+ protected getPreviousQueryParams(maxResults?: number): {
+ max_results?: number | undefined;
+ } & Partial & {
+ pagination_token: any;
+ };
+ protected getPageLengthFromRequest(result: TwitterResponse): any;
+ protected isFetchLastOver(result: TwitterResponse): boolean;
+ protected canFetchNextPage(result: TResult): boolean;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.js b/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.js
new file mode 100644
index 0000000..6e6e3c6
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/paginators/v2.paginator.js
@@ -0,0 +1,113 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TimelineV2Paginator = exports.TwitterV2Paginator = void 0;
+const includes_v2_helper_1 = require("../v2/includes.v2.helper");
+const TwitterPaginator_1 = require("./TwitterPaginator");
+/** A generic PreviousableTwitterPaginator with common v2 helper methods. */
+class TwitterV2Paginator extends TwitterPaginator_1.PreviousableTwitterPaginator {
+ updateIncludes(data) {
+ // Update errors
+ if (data.errors) {
+ if (!this._realData.errors) {
+ this._realData.errors = [];
+ }
+ this._realData.errors = [...this._realData.errors, ...data.errors];
+ }
+ // Update includes
+ if (!data.includes) {
+ return;
+ }
+ if (!this._realData.includes) {
+ this._realData.includes = {};
+ }
+ const includesRealData = this._realData.includes;
+ for (const [includeKey, includeArray] of Object.entries(data.includes)) {
+ if (!includesRealData[includeKey]) {
+ includesRealData[includeKey] = [];
+ }
+ includesRealData[includeKey] = [
+ ...includesRealData[includeKey],
+ ...includeArray,
+ ];
+ }
+ }
+ /** Throw if the current paginator is not usable. */
+ assertUsable() {
+ if (this.unusable) {
+ throw new Error('Unable to use this paginator to fetch more data, as it does not contain any metadata.' +
+ ' Check .errors property for more details.');
+ }
+ }
+ get meta() {
+ return this._realData.meta;
+ }
+ get includes() {
+ var _a;
+ if (!((_a = this._realData) === null || _a === void 0 ? void 0 : _a.includes)) {
+ return new includes_v2_helper_1.TwitterV2IncludesHelper(this._realData);
+ }
+ if (this._includesInstance) {
+ return this._includesInstance;
+ }
+ return this._includesInstance = new includes_v2_helper_1.TwitterV2IncludesHelper(this._realData);
+ }
+ get errors() {
+ var _a;
+ return (_a = this._realData.errors) !== null && _a !== void 0 ? _a : [];
+ }
+ /** `true` if this paginator only contains error payload and no metadata found to consume data. */
+ get unusable() {
+ return this.errors.length > 0 && !this._realData.meta && !this._realData.data;
+ }
+}
+exports.TwitterV2Paginator = TwitterV2Paginator;
+/** A generic TwitterV2Paginator able to consume v2 timelines that use max_results and pagination tokens. */
+class TimelineV2Paginator extends TwitterV2Paginator {
+ refreshInstanceFromResult(response, isNextPage) {
+ var _a;
+ const result = response.data;
+ const resultData = (_a = result.data) !== null && _a !== void 0 ? _a : [];
+ this._rateLimit = response.rateLimit;
+ if (!this._realData.data) {
+ this._realData.data = [];
+ }
+ if (isNextPage) {
+ this._realData.meta.result_count += result.meta.result_count;
+ this._realData.meta.next_token = result.meta.next_token;
+ this._realData.data.push(...resultData);
+ }
+ else {
+ this._realData.meta.result_count += result.meta.result_count;
+ this._realData.meta.previous_token = result.meta.previous_token;
+ this._realData.data.unshift(...resultData);
+ }
+ this.updateIncludes(result);
+ }
+ getNextQueryParams(maxResults) {
+ this.assertUsable();
+ return {
+ ...this.injectQueryParams(maxResults),
+ pagination_token: this._realData.meta.next_token,
+ };
+ }
+ getPreviousQueryParams(maxResults) {
+ this.assertUsable();
+ return {
+ ...this.injectQueryParams(maxResults),
+ pagination_token: this._realData.meta.previous_token,
+ };
+ }
+ getPageLengthFromRequest(result) {
+ var _a, _b;
+ return (_b = (_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
+ }
+ isFetchLastOver(result) {
+ var _a;
+ return !((_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) || !this.canFetchNextPage(result.data);
+ }
+ canFetchNextPage(result) {
+ var _a;
+ return !!((_a = result.meta) === null || _a === void 0 ? void 0 : _a.next_token);
+ }
+}
+exports.TimelineV2Paginator = TimelineV2Paginator;
diff --git a/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.d.ts b/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.d.ts
new file mode 100644
index 0000000..264d053
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.d.ts
@@ -0,0 +1,7 @@
+///
+import type { ClientRequestArgs } from 'http';
+import type { ClientRequestMaker } from '../client-mixins/request-maker.mixin';
+import { IGetHttpRequestArgs } from '../types';
+import type { IComputedHttpRequestArgs } from '../types/request-maker.mixin.types';
+export declare function hasRequestErrorPlugins(client: ClientRequestMaker): boolean;
+export declare function applyResponseHooks(this: ClientRequestMaker, requestParams: IGetHttpRequestArgs, computedParams: IComputedHttpRequestArgs, requestOptions: Partial, error: any): Promise;
diff --git a/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.js b/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.js
new file mode 100644
index 0000000..66452e2
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/plugins/helpers.js
@@ -0,0 +1,46 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.applyResponseHooks = exports.hasRequestErrorPlugins = void 0;
+const types_1 = require("../types");
+/* Plugin helpers */
+function hasRequestErrorPlugins(client) {
+ var _a;
+ if (!((_a = client.clientSettings.plugins) === null || _a === void 0 ? void 0 : _a.length)) {
+ return false;
+ }
+ for (const plugin of client.clientSettings.plugins) {
+ if (plugin.onRequestError || plugin.onResponseError) {
+ return true;
+ }
+ }
+ return false;
+}
+exports.hasRequestErrorPlugins = hasRequestErrorPlugins;
+async function applyResponseHooks(requestParams, computedParams, requestOptions, error) {
+ let override;
+ if (error instanceof types_1.ApiRequestError || error instanceof types_1.ApiPartialResponseError) {
+ override = await this.applyPluginMethod('onRequestError', {
+ client: this,
+ url: this.getUrlObjectFromUrlString(requestParams.url),
+ params: requestParams,
+ computedParams,
+ requestOptions,
+ error,
+ });
+ }
+ else if (error instanceof types_1.ApiResponseError) {
+ override = await this.applyPluginMethod('onResponseError', {
+ client: this,
+ url: this.getUrlObjectFromUrlString(requestParams.url),
+ params: requestParams,
+ computedParams,
+ requestOptions,
+ error,
+ });
+ }
+ if (override && override instanceof types_1.TwitterApiPluginResponseOverride) {
+ return override.value;
+ }
+ return Promise.reject(error);
+}
+exports.applyResponseHooks = applyResponseHooks;
diff --git a/node_modules/twitter-api-v2/dist/cjs/settings.d.ts b/node_modules/twitter-api-v2/dist/cjs/settings.d.ts
new file mode 100644
index 0000000..5a8d18e
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/settings.d.ts
@@ -0,0 +1,9 @@
+export interface ITwitterApiV2Settings {
+ debug: boolean;
+ deprecationWarnings: boolean;
+ logger: ITwitterApiV2SettingsLogger;
+}
+export interface ITwitterApiV2SettingsLogger {
+ log(message: string, payload?: any): void;
+}
+export declare const TwitterApiV2Settings: ITwitterApiV2Settings;
diff --git a/node_modules/twitter-api-v2/dist/cjs/settings.js b/node_modules/twitter-api-v2/dist/cjs/settings.js
new file mode 100644
index 0000000..5604a75
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/settings.js
@@ -0,0 +1,8 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TwitterApiV2Settings = void 0;
+exports.TwitterApiV2Settings = {
+ debug: false,
+ deprecationWarnings: true,
+ logger: { log: console.log.bind(console) },
+};
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.d.ts b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.d.ts
new file mode 100644
index 0000000..d84cf71
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.d.ts
@@ -0,0 +1,83 @@
+///
+///
+///
+///
+import { EventEmitter } from 'events';
+import type { IncomingMessage, ClientRequest } from 'http';
+import type { Readable } from 'stream';
+import { ETwitterStreamEvent } from '../types';
+import { TRequestFullStreamData } from '../types/request-maker.mixin.types';
+import TweetStreamParser from './TweetStreamParser';
+export interface ITweetStreamError {
+ type: ETwitterStreamEvent.ConnectionError | ETwitterStreamEvent.TweetParseError | ETwitterStreamEvent.ReconnectError | ETwitterStreamEvent.DataError | ETwitterStreamEvent.ConnectError;
+ error: any;
+ message?: string;
+}
+export interface IConnectTweetStreamParams {
+ autoReconnect: boolean;
+ autoReconnectRetries: number | 'unlimited';
+ /** Check for 'lost connection' status every `keepAliveTimeout` milliseconds. Defaults to 2 minutes (`120000`). */
+ keepAliveTimeout: number | 'disable';
+ nextRetryTimeout?: TStreamConnectRetryFn;
+}
+export interface IWithConnectionTweetStream {
+ req: ClientRequest;
+ res: Readable;
+ originalResponse: IncomingMessage;
+}
+/** Returns a number of milliseconds to wait for {tryOccurrence} (starting from 1) */
+export declare type TStreamConnectRetryFn = (tryOccurrence: number, error?: any) => number;
+export declare class TweetStream extends EventEmitter {
+ protected requestData: TRequestFullStreamData;
+ autoReconnect: boolean;
+ autoReconnectRetries: number;
+ keepAliveTimeoutMs: number;
+ nextRetryTimeout: TStreamConnectRetryFn;
+ protected retryTimeout?: NodeJS.Timeout;
+ protected keepAliveTimeout?: NodeJS.Timeout;
+ protected parser: TweetStreamParser;
+ protected connectionProcessRunning: boolean;
+ protected req?: ClientRequest;
+ protected res?: Readable;
+ protected originalResponse?: IncomingMessage;
+ constructor(requestData: TRequestFullStreamData, connection?: IWithConnectionTweetStream);
+ on(event: ETwitterStreamEvent.Data, handler: (data: T) => any): this;
+ on(event: ETwitterStreamEvent.DataError, handler: (error: any) => any): this;
+ on(event: ETwitterStreamEvent.Error, handler: (errorPayload: ITweetStreamError) => any): this;
+ on(event: ETwitterStreamEvent.Connected, handler: () => any): this;
+ on(event: ETwitterStreamEvent.ConnectionLost, handler: () => any): this;
+ on(event: ETwitterStreamEvent.ConnectionError, handler: (error: Error) => any): this;
+ on(event: ETwitterStreamEvent.TweetParseError, handler: (error: Error) => any): this;
+ on(event: ETwitterStreamEvent.ConnectionClosed, handler: () => any): this;
+ on(event: ETwitterStreamEvent.DataKeepAlive, handler: () => any): this;
+ on(event: ETwitterStreamEvent.ReconnectAttempt, handler: (tries: number) => any): this;
+ on(event: ETwitterStreamEvent.ReconnectError, handler: (tries: number) => any): this;
+ on(event: ETwitterStreamEvent.ReconnectLimitExceeded, handler: () => any): this;
+ on(event: ETwitterStreamEvent.Reconnected, handler: () => any): this;
+ on(event: string | symbol, handler: (...args: any[]) => any): this;
+ protected initEventsFromRequest(): void;
+ protected initEventsFromParser(): void;
+ protected resetKeepAliveTimeout(): void;
+ protected onKeepAliveTimeout(): void;
+ protected unbindTimeouts(): void;
+ protected unbindKeepAliveTimeout(): void;
+ protected unbindRetryTimeout(): void;
+ protected closeWithoutEmit(): void;
+ /** Terminate connection to Twitter. */
+ close(): void;
+ /** Unbind all listeners, and close connection. */
+ destroy(): void;
+ /**
+ * Make a new request that creates a new `TweetStream` instance with
+ * the same parameters, and bind current listeners to new stream.
+ */
+ clone(): Promise>;
+ /** Start initial stream connection, setup options on current instance and returns itself. */
+ connect(options?: Partial): Promise;
+ /** Make a new request to (re)connect to Twitter. */
+ reconnect(): Promise;
+ protected onConnectionError(retryOccurrence?: number): Promise;
+ protected makeAutoReconnectRetry(retryOccurrence: number, error: any): void;
+ [Symbol.asyncIterator](): AsyncGenerator;
+}
+export default TweetStream;
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.js b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.js
new file mode 100644
index 0000000..de6bffd
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStream.js
@@ -0,0 +1,303 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TweetStream = void 0;
+const events_1 = require("events");
+const request_handler_helper_1 = __importDefault(require("../client-mixins/request-handler.helper"));
+const types_1 = require("../types");
+const TweetStreamEventCombiner_1 = __importDefault(require("./TweetStreamEventCombiner"));
+const TweetStreamParser_1 = __importStar(require("./TweetStreamParser"));
+// In seconds
+const basicRetriesAttempt = [5, 15, 30, 60, 90, 120, 180, 300, 600, 900];
+// Default retry function
+const basicReconnectRetry = tryOccurrence => tryOccurrence > basicRetriesAttempt.length
+ ? 901000
+ : basicRetriesAttempt[tryOccurrence - 1] * 1000;
+class TweetStream extends events_1.EventEmitter {
+ constructor(requestData, connection) {
+ super();
+ this.requestData = requestData;
+ this.autoReconnect = false;
+ this.autoReconnectRetries = 5;
+ // 2 minutes without any Twitter signal
+ this.keepAliveTimeoutMs = 1000 * 120;
+ this.nextRetryTimeout = basicReconnectRetry;
+ this.parser = new TweetStreamParser_1.default();
+ this.connectionProcessRunning = false;
+ this.onKeepAliveTimeout = this.onKeepAliveTimeout.bind(this);
+ this.initEventsFromParser();
+ if (connection) {
+ this.req = connection.req;
+ this.res = connection.res;
+ this.originalResponse = connection.originalResponse;
+ this.initEventsFromRequest();
+ }
+ }
+ on(event, handler) {
+ return super.on(event, handler);
+ }
+ initEventsFromRequest() {
+ if (!this.req || !this.res) {
+ throw new Error('TweetStream error: You cannot init TweetStream without a request and response object.');
+ }
+ const errorHandler = (err) => {
+ this.emit(types_1.ETwitterStreamEvent.ConnectionError, err);
+ this.emit(types_1.ETwitterStreamEvent.Error, {
+ type: types_1.ETwitterStreamEvent.ConnectionError,
+ error: err,
+ message: 'Connection lost or closed by Twitter.',
+ });
+ this.onConnectionError();
+ };
+ this.req.on('error', errorHandler);
+ this.res.on('error', errorHandler);
+ // Usually, connection should not be closed by Twitter!
+ this.res.on('close', () => errorHandler(new Error('Connection closed by Twitter.')));
+ this.res.on('data', (chunk) => {
+ this.resetKeepAliveTimeout();
+ if (chunk.toString() === '\r\n') {
+ return this.emit(types_1.ETwitterStreamEvent.DataKeepAlive);
+ }
+ this.parser.push(chunk.toString());
+ });
+ // Starts the keep alive timeout
+ this.resetKeepAliveTimeout();
+ }
+ initEventsFromParser() {
+ const payloadIsError = this.requestData.payloadIsError;
+ this.parser.on(TweetStreamParser_1.EStreamParserEvent.ParsedData, (eventData) => {
+ if (payloadIsError && payloadIsError(eventData)) {
+ this.emit(types_1.ETwitterStreamEvent.DataError, eventData);
+ this.emit(types_1.ETwitterStreamEvent.Error, {
+ type: types_1.ETwitterStreamEvent.DataError,
+ error: eventData,
+ message: 'Twitter sent a payload that is detected as an error payload.',
+ });
+ }
+ else {
+ this.emit(types_1.ETwitterStreamEvent.Data, eventData);
+ }
+ });
+ this.parser.on(TweetStreamParser_1.EStreamParserEvent.ParseError, (error) => {
+ this.emit(types_1.ETwitterStreamEvent.TweetParseError, error);
+ this.emit(types_1.ETwitterStreamEvent.Error, {
+ type: types_1.ETwitterStreamEvent.TweetParseError,
+ error,
+ message: 'Failed to parse stream data.',
+ });
+ });
+ }
+ resetKeepAliveTimeout() {
+ this.unbindKeepAliveTimeout();
+ if (this.keepAliveTimeoutMs !== Infinity) {
+ this.keepAliveTimeout = setTimeout(this.onKeepAliveTimeout, this.keepAliveTimeoutMs);
+ }
+ }
+ onKeepAliveTimeout() {
+ this.emit(types_1.ETwitterStreamEvent.ConnectionLost);
+ this.onConnectionError();
+ }
+ unbindTimeouts() {
+ this.unbindRetryTimeout();
+ this.unbindKeepAliveTimeout();
+ }
+ unbindKeepAliveTimeout() {
+ if (this.keepAliveTimeout) {
+ clearTimeout(this.keepAliveTimeout);
+ this.keepAliveTimeout = undefined;
+ }
+ }
+ unbindRetryTimeout() {
+ if (this.retryTimeout) {
+ clearTimeout(this.retryTimeout);
+ this.retryTimeout = undefined;
+ }
+ }
+ closeWithoutEmit() {
+ this.unbindTimeouts();
+ if (this.res) {
+ this.res.removeAllListeners();
+ // Close response silently
+ this.res.destroy();
+ }
+ if (this.req) {
+ this.req.removeAllListeners();
+ // Close connection silently
+ this.req.destroy();
+ }
+ }
+ /** Terminate connection to Twitter. */
+ close() {
+ this.emit(types_1.ETwitterStreamEvent.ConnectionClosed);
+ this.closeWithoutEmit();
+ }
+ /** Unbind all listeners, and close connection. */
+ destroy() {
+ this.removeAllListeners();
+ this.close();
+ }
+ /**
+ * Make a new request that creates a new `TweetStream` instance with
+ * the same parameters, and bind current listeners to new stream.
+ */
+ async clone() {
+ const newRequest = new request_handler_helper_1.default(this.requestData);
+ const newStream = await newRequest.makeRequestAsStream();
+ // Clone attached listeners
+ const listenerNames = this.eventNames();
+ for (const listener of listenerNames) {
+ const callbacks = this.listeners(listener);
+ for (const callback of callbacks) {
+ newStream.on(listener, callback);
+ }
+ }
+ return newStream;
+ }
+ /** Start initial stream connection, setup options on current instance and returns itself. */
+ async connect(options = {}) {
+ if (typeof options.autoReconnect !== 'undefined') {
+ this.autoReconnect = options.autoReconnect;
+ }
+ if (typeof options.autoReconnectRetries !== 'undefined') {
+ this.autoReconnectRetries = options.autoReconnectRetries === 'unlimited'
+ ? Infinity
+ : options.autoReconnectRetries;
+ }
+ if (typeof options.keepAliveTimeout !== 'undefined') {
+ this.keepAliveTimeoutMs = options.keepAliveTimeout === 'disable'
+ ? Infinity
+ : options.keepAliveTimeout;
+ }
+ if (typeof options.nextRetryTimeout !== 'undefined') {
+ this.nextRetryTimeout = options.nextRetryTimeout;
+ }
+ // Make the connection
+ this.unbindTimeouts();
+ try {
+ await this.reconnect();
+ }
+ catch (e) {
+ this.emit(types_1.ETwitterStreamEvent.ConnectError, 0);
+ this.emit(types_1.ETwitterStreamEvent.Error, {
+ type: types_1.ETwitterStreamEvent.ConnectError,
+ error: e,
+ message: 'Connect error - Initial connection just failed.',
+ });
+ // Only make a reconnection attempt if autoReconnect is true!
+ // Otherwise, let error be propagated
+ if (this.autoReconnect) {
+ this.makeAutoReconnectRetry(0, e);
+ }
+ else {
+ throw e;
+ }
+ }
+ return this;
+ }
+ /** Make a new request to (re)connect to Twitter. */
+ async reconnect() {
+ if (this.connectionProcessRunning) {
+ throw new Error('Connection process is already running.');
+ }
+ this.connectionProcessRunning = true;
+ try {
+ let initialConnection = true;
+ if (this.req) {
+ initialConnection = false;
+ this.closeWithoutEmit();
+ }
+ const { req, res, originalResponse } = await new request_handler_helper_1.default(this.requestData).makeRequestAndResolveWhenReady();
+ this.req = req;
+ this.res = res;
+ this.originalResponse = originalResponse;
+ this.emit(initialConnection ? types_1.ETwitterStreamEvent.Connected : types_1.ETwitterStreamEvent.Reconnected);
+ this.parser.reset();
+ this.initEventsFromRequest();
+ }
+ finally {
+ this.connectionProcessRunning = false;
+ }
+ }
+ async onConnectionError(retryOccurrence = 0) {
+ this.unbindTimeouts();
+ // Close the request if necessary
+ this.closeWithoutEmit();
+ // Terminate stream by events if necessary (no auto-reconnect or retries exceeded)
+ if (!this.autoReconnect) {
+ this.emit(types_1.ETwitterStreamEvent.ConnectionClosed);
+ return;
+ }
+ if (retryOccurrence >= this.autoReconnectRetries) {
+ this.emit(types_1.ETwitterStreamEvent.ReconnectLimitExceeded);
+ this.emit(types_1.ETwitterStreamEvent.ConnectionClosed);
+ return;
+ }
+ // If all other conditions fails, do a reconnect attempt
+ try {
+ this.emit(types_1.ETwitterStreamEvent.ReconnectAttempt, retryOccurrence);
+ await this.reconnect();
+ }
+ catch (e) {
+ this.emit(types_1.ETwitterStreamEvent.ReconnectError, retryOccurrence);
+ this.emit(types_1.ETwitterStreamEvent.Error, {
+ type: types_1.ETwitterStreamEvent.ReconnectError,
+ error: e,
+ message: `Reconnect error - ${retryOccurrence + 1} attempts made yet.`,
+ });
+ this.makeAutoReconnectRetry(retryOccurrence, e);
+ }
+ }
+ makeAutoReconnectRetry(retryOccurrence, error) {
+ const nextRetry = this.nextRetryTimeout(retryOccurrence + 1, error);
+ this.retryTimeout = setTimeout(() => {
+ this.onConnectionError(retryOccurrence + 1);
+ }, nextRetry);
+ }
+ async *[Symbol.asyncIterator]() {
+ const eventCombiner = new TweetStreamEventCombiner_1.default(this);
+ try {
+ while (true) {
+ if (!this.req || this.req.aborted) {
+ throw new Error('Connection closed');
+ }
+ if (eventCombiner.hasStack()) {
+ yield* eventCombiner.popStack();
+ }
+ const { type, payload } = await eventCombiner.nextEvent();
+ if (type === 'error') {
+ throw payload;
+ }
+ }
+ }
+ finally {
+ eventCombiner.destroy();
+ }
+ }
+}
+exports.TweetStream = TweetStream;
+exports.default = TweetStream;
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.d.ts b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.d.ts
new file mode 100644
index 0000000..e268000
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.d.ts
@@ -0,0 +1,27 @@
+///
+import { EventEmitter } from 'events';
+import type TweetStream from './TweetStream';
+export declare class TweetStreamEventCombiner extends EventEmitter {
+ private stream;
+ private stack;
+ private onceNewEvent;
+ constructor(stream: TweetStream);
+ /** Returns a new `Promise` that will `resolve` on next event (`data` or any sort of error). */
+ nextEvent(): Promise<{
+ type: "error";
+ payload?: any;
+ } | {
+ type: "data";
+ payload: T;
+ }>;
+ /** Returns `true` if there's something in the stack. */
+ hasStack(): boolean;
+ /** Returns stacked data events, and clean the stack. */
+ popStack(): T[];
+ /** Cleanup all the listeners attached on stream. */
+ destroy(): void;
+ private emitEvent;
+ private onStreamError;
+ private onStreamData;
+}
+export default TweetStreamEventCombiner;
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.js b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.js
new file mode 100644
index 0000000..4e9a295
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamEventCombiner.js
@@ -0,0 +1,55 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TweetStreamEventCombiner = void 0;
+const events_1 = require("events");
+const types_1 = require("../types");
+class TweetStreamEventCombiner extends events_1.EventEmitter {
+ constructor(stream) {
+ super();
+ this.stream = stream;
+ this.stack = [];
+ this.onStreamData = this.onStreamData.bind(this);
+ this.onStreamError = this.onStreamError.bind(this);
+ this.onceNewEvent = this.once.bind(this, 'event');
+ // Init events from stream
+ stream.on(types_1.ETwitterStreamEvent.Data, this.onStreamData);
+ // Ignore reconnect errors: Don't close event combiner until connection error/closed
+ stream.on(types_1.ETwitterStreamEvent.ConnectionError, this.onStreamError);
+ stream.on(types_1.ETwitterStreamEvent.TweetParseError, this.onStreamError);
+ stream.on(types_1.ETwitterStreamEvent.ConnectionClosed, this.onStreamError);
+ }
+ /** Returns a new `Promise` that will `resolve` on next event (`data` or any sort of error). */
+ nextEvent() {
+ return new Promise(this.onceNewEvent);
+ }
+ /** Returns `true` if there's something in the stack. */
+ hasStack() {
+ return this.stack.length > 0;
+ }
+ /** Returns stacked data events, and clean the stack. */
+ popStack() {
+ const stack = this.stack;
+ this.stack = [];
+ return stack;
+ }
+ /** Cleanup all the listeners attached on stream. */
+ destroy() {
+ this.removeAllListeners();
+ this.stream.off(types_1.ETwitterStreamEvent.Data, this.onStreamData);
+ this.stream.off(types_1.ETwitterStreamEvent.ConnectionError, this.onStreamError);
+ this.stream.off(types_1.ETwitterStreamEvent.TweetParseError, this.onStreamError);
+ this.stream.off(types_1.ETwitterStreamEvent.ConnectionClosed, this.onStreamError);
+ }
+ emitEvent(type, payload) {
+ this.emit('event', { type, payload });
+ }
+ onStreamError(payload) {
+ this.emitEvent('error', payload);
+ }
+ onStreamData(payload) {
+ this.stack.push(payload);
+ this.emitEvent('data', payload);
+ }
+}
+exports.TweetStreamEventCombiner = TweetStreamEventCombiner;
+exports.default = TweetStreamEventCombiner;
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.d.ts b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.d.ts
new file mode 100644
index 0000000..459fcbb
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.d.ts
@@ -0,0 +1,12 @@
+///
+import { EventEmitter } from 'events';
+export default class TweetStreamParser extends EventEmitter {
+ protected currentMessage: string;
+ push(chunk: string): void;
+ /** Reset the currently stored message (f.e. on connection reset) */
+ reset(): void;
+}
+export declare enum EStreamParserEvent {
+ ParsedData = "parsed data",
+ ParseError = "parse error"
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.js b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.js
new file mode 100644
index 0000000..8b8e5ee
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/stream/TweetStreamParser.js
@@ -0,0 +1,54 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.EStreamParserEvent = void 0;
+const events_1 = require("events");
+class TweetStreamParser extends events_1.EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.currentMessage = '';
+ }
+ // Code partially belongs to twitter-stream-api for this
+ // https://github.com/trygve-lie/twitter-stream-api/blob/master/lib/parser.js
+ push(chunk) {
+ this.currentMessage += chunk;
+ chunk = this.currentMessage;
+ const size = chunk.length;
+ let start = 0;
+ let offset = 0;
+ while (offset < size) {
+ // Take [offset, offset+1] inside a new string
+ if (chunk.slice(offset, offset + 2) === '\r\n') {
+ // If chunk contains \r\n after current offset,
+ // parse [start, ..., offset] as a tweet
+ const piece = chunk.slice(start, offset);
+ start = offset += 2;
+ // If empty object
+ if (!piece.length) {
+ continue;
+ }
+ try {
+ const payload = JSON.parse(piece);
+ if (payload) {
+ this.emit(EStreamParserEvent.ParsedData, payload);
+ continue;
+ }
+ }
+ catch (error) {
+ this.emit(EStreamParserEvent.ParseError, error);
+ }
+ }
+ offset++;
+ }
+ this.currentMessage = chunk.slice(start, size);
+ }
+ /** Reset the currently stored message (f.e. on connection reset) */
+ reset() {
+ this.currentMessage = '';
+ }
+}
+exports.default = TweetStreamParser;
+var EStreamParserEvent;
+(function (EStreamParserEvent) {
+ EStreamParserEvent["ParsedData"] = "parsed data";
+ EStreamParserEvent["ParseError"] = "parse error";
+})(EStreamParserEvent = exports.EStreamParserEvent || (exports.EStreamParserEvent = {}));
diff --git a/node_modules/twitter-api-v2/dist/cjs/test/utils.d.ts b/node_modules/twitter-api-v2/dist/cjs/test/utils.d.ts
new file mode 100644
index 0000000..840fb61
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/test/utils.d.ts
@@ -0,0 +1,25 @@
+import { TwitterApi } from '..';
+/** User OAuth 1.0a client */
+export declare function getUserClient(this: any): TwitterApi;
+export declare function getUserKeys(): {
+ appKey: string;
+ appSecret: string;
+ accessToken: string;
+ accessSecret: string;
+};
+export declare function sleepTest(ms: number): Promise;
+/** User-unlogged OAuth 1.0a client */
+export declare function getRequestClient(): TwitterApi;
+export declare function getRequestKeys(): {
+ appKey: string;
+ appSecret: string;
+};
+export declare function getAuthLink(callback: string): Promise<{
+ oauth_token: string;
+ oauth_token_secret: string;
+ oauth_callback_confirmed: "true";
+ url: string;
+}>;
+export declare function getAccessClient(verifier: string): Promise;
+/** App OAuth 2.0 client */
+export declare function getAppClient(): Promise;
diff --git a/node_modules/twitter-api-v2/dist/cjs/test/utils.js b/node_modules/twitter-api-v2/dist/cjs/test/utils.js
new file mode 100644
index 0000000..8a73b19
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/test/utils.js
@@ -0,0 +1,99 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getAppClient = exports.getAccessClient = exports.getAuthLink = exports.getRequestKeys = exports.getRequestClient = exports.sleepTest = exports.getUserKeys = exports.getUserClient = void 0;
+const __1 = require("..");
+const dotenv = __importStar(require("dotenv"));
+dotenv.config({ path: __dirname + '/../../.env' });
+/** User OAuth 1.0a client */
+function getUserClient() {
+ return new __1.TwitterApi({
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ accessToken: process.env.OAUTH_TOKEN,
+ accessSecret: process.env.OAUTH_SECRET,
+ });
+}
+exports.getUserClient = getUserClient;
+function getUserKeys() {
+ return {
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ accessToken: process.env.OAUTH_TOKEN,
+ accessSecret: process.env.OAUTH_SECRET,
+ };
+}
+exports.getUserKeys = getUserKeys;
+async function sleepTest(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+exports.sleepTest = sleepTest;
+/** User-unlogged OAuth 1.0a client */
+function getRequestClient() {
+ return new __1.TwitterApi({
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ });
+}
+exports.getRequestClient = getRequestClient;
+function getRequestKeys() {
+ return {
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ };
+}
+exports.getRequestKeys = getRequestKeys;
+// Test auth 1.0a flow
+function getAuthLink(callback) {
+ return getRequestClient().generateAuthLink(callback);
+}
+exports.getAuthLink = getAuthLink;
+async function getAccessClient(verifier) {
+ const requestClient = new __1.TwitterApi({
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ accessToken: process.env.OAUTH_TOKEN,
+ accessSecret: process.env.OAUTH_SECRET,
+ });
+ const { client } = await requestClient.login(verifier);
+ return client;
+}
+exports.getAccessClient = getAccessClient;
+/** App OAuth 2.0 client */
+function getAppClient() {
+ let requestClient;
+ if (process.env.BEARER_TOKEN) {
+ requestClient = new __1.TwitterApi(process.env.BEARER_TOKEN);
+ return Promise.resolve(requestClient);
+ }
+ else {
+ requestClient = new __1.TwitterApi({
+ appKey: process.env.CONSUMER_TOKEN,
+ appSecret: process.env.CONSUMER_SECRET,
+ });
+ return requestClient.appLogin();
+ }
+}
+exports.getAppClient = getAppClient;
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/auth.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/auth.types.d.ts
new file mode 100644
index 0000000..6f31060
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/auth.types.d.ts
@@ -0,0 +1,63 @@
+import type TwitterApi from '../client';
+import { TypeOrArrayOf } from './shared.types';
+export declare type TOAuth2Scope = 'tweet.read' | 'tweet.write' | 'tweet.moderate.write' | 'users.read' | 'follows.read' | 'follows.write' | 'offline.access' | 'space.read' | 'mute.read' | 'mute.write' | 'like.read' | 'like.write' | 'list.read' | 'list.write' | 'block.read' | 'block.write' | 'bookmark.read' | 'bookmark.write' | 'dm.read' | 'dm.write';
+export interface BuildOAuth2RequestLinkArgs {
+ scope?: TypeOrArrayOf | TypeOrArrayOf;
+ state?: string;
+}
+export interface AccessOAuth2TokenArgs {
+ /** The same URI given to generate link at previous step. */
+ redirectUri: string;
+ /** The code obtained in link generation step. */
+ codeVerifier: string;
+ /** The code given by Twitter in query string, after redirection to your callback URL. */
+ code: string;
+}
+export interface AccessOAuth2TokenResult {
+ token_type: 'bearer';
+ expires_in: number;
+ access_token: string;
+ scope: string;
+ refresh_token?: string;
+}
+export interface RequestTokenArgs {
+ authAccessType: 'read' | 'write';
+ linkMode: 'authenticate' | 'authorize';
+ forceLogin: boolean;
+ screenName: string;
+}
+export interface RequestTokenResult {
+ oauth_token: string;
+ oauth_token_secret: string;
+ oauth_callback_confirmed: 'true';
+}
+export interface IOAuth2RequestTokenResult {
+ url: string;
+ state: string;
+ codeVerifier: string;
+ codeChallenge: string;
+}
+export interface AccessTokenResult {
+ oauth_token: string;
+ oauth_token_secret: string;
+ user_id: string;
+ screen_name: string;
+}
+export interface BearerTokenResult {
+ token_type: 'bearer';
+ access_token: string;
+}
+export interface LoginResult {
+ userId: string;
+ screenName: string;
+ accessToken: string;
+ accessSecret: string;
+ client: TwitterApi;
+}
+export interface IParsedOAuth2TokenResult {
+ client: TwitterApi;
+ expiresIn: number;
+ accessToken: string;
+ scope: TOAuth2Scope[];
+ refreshToken?: string;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/auth.types.js b/node_modules/twitter-api-v2/dist/cjs/types/auth.types.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/auth.types.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/client.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/client.types.d.ts
new file mode 100644
index 0000000..b381234
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/client.types.d.ts
@@ -0,0 +1,63 @@
+///
+import type { Agent } from 'http';
+import type { ITwitterApiClientPlugin } from './plugins';
+import type { TRequestCompressionLevel } from './request-maker.mixin.types';
+export declare enum ETwitterStreamEvent {
+ Connected = "connected",
+ ConnectError = "connect error",
+ ConnectionError = "connection error",
+ ConnectionClosed = "connection closed",
+ ConnectionLost = "connection lost",
+ ReconnectAttempt = "reconnect attempt",
+ Reconnected = "reconnected",
+ ReconnectError = "reconnect error",
+ ReconnectLimitExceeded = "reconnect limit exceeded",
+ DataKeepAlive = "data keep-alive",
+ Data = "data event content",
+ DataError = "data twitter error",
+ TweetParseError = "data tweet parse error",
+ Error = "stream error"
+}
+export interface TwitterApiTokens {
+ appKey: string;
+ appSecret: string;
+ accessToken?: string;
+ accessSecret?: string;
+}
+export interface TwitterApiOAuth2Init {
+ clientId: string;
+ clientSecret?: string;
+}
+export interface TwitterApiBasicAuth {
+ username: string;
+ password: string;
+}
+export interface IClientTokenBearer {
+ bearerToken: string;
+ type: 'oauth2';
+}
+export interface IClientOAuth2UserClient {
+ clientId: string;
+ type: 'oauth2-user';
+}
+export interface IClientTokenBasic {
+ token: string;
+ type: 'basic';
+}
+export interface IClientTokenOauth {
+ appKey: string;
+ appSecret: string;
+ accessToken?: string;
+ accessSecret?: string;
+ type: 'oauth-1.0a';
+}
+export interface IClientTokenNone {
+ type: 'none';
+}
+export declare type TClientTokens = IClientTokenNone | IClientTokenBearer | IClientTokenOauth | IClientTokenBasic | IClientOAuth2UserClient;
+export interface IClientSettings {
+ /** Used to send HTTPS requests. This is mostly used to make requests work behind a proxy. */
+ httpAgent: Agent;
+ plugins: ITwitterApiClientPlugin[];
+ compression: TRequestCompressionLevel;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/client.types.js b/node_modules/twitter-api-v2/dist/cjs/types/client.types.js
new file mode 100644
index 0000000..a0430a2
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/client.types.js
@@ -0,0 +1,20 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ETwitterStreamEvent = void 0;
+var ETwitterStreamEvent;
+(function (ETwitterStreamEvent) {
+ ETwitterStreamEvent["Connected"] = "connected";
+ ETwitterStreamEvent["ConnectError"] = "connect error";
+ ETwitterStreamEvent["ConnectionError"] = "connection error";
+ ETwitterStreamEvent["ConnectionClosed"] = "connection closed";
+ ETwitterStreamEvent["ConnectionLost"] = "connection lost";
+ ETwitterStreamEvent["ReconnectAttempt"] = "reconnect attempt";
+ ETwitterStreamEvent["Reconnected"] = "reconnected";
+ ETwitterStreamEvent["ReconnectError"] = "reconnect error";
+ ETwitterStreamEvent["ReconnectLimitExceeded"] = "reconnect limit exceeded";
+ ETwitterStreamEvent["DataKeepAlive"] = "data keep-alive";
+ ETwitterStreamEvent["Data"] = "data event content";
+ ETwitterStreamEvent["DataError"] = "data twitter error";
+ ETwitterStreamEvent["TweetParseError"] = "data tweet parse error";
+ ETwitterStreamEvent["Error"] = "stream error";
+})(ETwitterStreamEvent = exports.ETwitterStreamEvent || (exports.ETwitterStreamEvent = {}));
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/entities.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/entities.types.d.ts
new file mode 100644
index 0000000..2a3cbaa
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/entities.types.d.ts
@@ -0,0 +1,18 @@
+export interface Entity {
+ start: number;
+ end: number;
+}
+export interface UrlEntity extends Entity {
+ url: string;
+ expanded_url: string;
+ display_url: string;
+}
+export interface HashtagEntity extends Entity {
+ hashtag: string;
+}
+export interface CashtagEntity extends Entity {
+ cashtag: string;
+}
+export interface MentionEntity extends Entity {
+ username: string;
+}
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/entities.types.js b/node_modules/twitter-api-v2/dist/cjs/types/entities.types.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/entities.types.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/errors.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/errors.types.d.ts
new file mode 100644
index 0000000..5dc5a43
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/errors.types.d.ts
@@ -0,0 +1,205 @@
+///
+import type { TwitterRateLimit, TwitterResponse } from '../types';
+import type { ClientRequest, IncomingMessage, IncomingHttpHeaders } from 'http';
+export interface ErrorV1 {
+ code: number;
+ message: string;
+}
+/** Errors included in response payload with a OK HTTP status (code ~= 200) */
+export interface InlineErrorV2 {
+ value?: string;
+ detail: string;
+ title: string;
+ resource_type?: string;
+ parameter?: string;
+ resource_id?: string;
+ reason?: string;
+ type: string;
+}
+/** Error payload thrown when HTTP code is not OK */
+export interface ErrorV2 {
+ detail: string;
+ title: string;
+ type: string;
+ errors: {
+ message: string;
+ parameters?: {
+ [parameterName: string]: string[];
+ };
+ }[];
+}
+export declare type TRequestError = TwitterApiRequestError | TwitterApiError;
+export interface TwitterErrorPayload {
+ request: ClientRequest;
+ rawResponse?: IncomingMessage;
+ response?: TwitterResponse;
+ error?: Error;
+}
+export interface TwitterApiErrorData {
+ errors?: (ErrorV1 | ErrorV2)[];
+ error?: string;
+ title?: string;
+ detail?: string;
+ type?: string;
+}
+export declare enum ETwitterApiError {
+ Request = "request",
+ PartialResponse = "partial-response",
+ Response = "response"
+}
+export interface TwitterApiRequestError {
+ type: ETwitterApiError.Request;
+ error: true;
+ readonly requestError: Error;
+}
+export interface TwitterApiError extends TwitterResponse {
+ type: ETwitterApiError.Response;
+ error: true;
+ /** HTTP status code */
+ code: number;
+}
+declare abstract class ApiError extends Error {
+ abstract type: ETwitterApiError.Request | ETwitterApiError.Response | ETwitterApiError.PartialResponse;
+ abstract request: ClientRequest;
+ error: true;
+}
+interface IBuildApiRequestError {
+ readonly request: ClientRequest;
+ error: Error;
+}
+export declare class ApiRequestError extends ApiError implements TwitterApiRequestError {
+ protected _options: any;
+ type: ETwitterApiError.Request;
+ constructor(message: string, options: IBuildApiRequestError);
+ get request(): ClientRequest;
+ get requestError(): Error;
+ toJSON(): {
+ type: ETwitterApiError.Request;
+ error: Error;
+ };
+}
+interface IBuildApiPartialRequestError {
+ readonly request: ClientRequest;
+ readonly response: IncomingMessage;
+ readonly rawContent: string;
+ responseError: Error;
+}
+export declare class ApiPartialResponseError extends ApiError implements IBuildApiPartialRequestError {
+ protected _options: any;
+ type: ETwitterApiError.PartialResponse;
+ constructor(message: string, options: IBuildApiPartialRequestError);
+ get request(): ClientRequest;
+ get response(): IncomingMessage;
+ get responseError(): Error;
+ get rawContent(): string;
+ toJSON(): {
+ type: ETwitterApiError.PartialResponse;
+ error: Error;
+ };
+}
+interface IBuildApiResponseError {
+ code: number;
+ request: ClientRequest;
+ response: IncomingMessage;
+ headers: IncomingHttpHeaders;
+ data: TwitterApiErrorData;
+ rateLimit?: TwitterRateLimit;
+}
+export declare class ApiResponseError extends ApiError implements TwitterApiError, IBuildApiResponseError {
+ protected _options: any;
+ type: ETwitterApiError.Response;
+ /** HTTP error code */
+ code: number;
+ headers: IncomingHttpHeaders;
+ data: TwitterApiErrorData;
+ rateLimit?: TwitterRateLimit;
+ constructor(message: string, options: IBuildApiResponseError);
+ get request(): ClientRequest;
+ get response(): IncomingMessage;
+ /** Check for presence of one of given v1/v2 error codes. */
+ hasErrorCode(...codes: (EApiV1ErrorCode | number)[] | (EApiV2ErrorCode | string)[]): boolean;
+ get errors(): (ErrorV1 | ErrorV2)[] | undefined;
+ get rateLimitError(): boolean;
+ get isAuthError(): boolean;
+ toJSON(): {
+ type: ETwitterApiError.Response;
+ code: number;
+ error: TwitterApiErrorData;
+ rateLimit: TwitterRateLimit | undefined;
+ headers: IncomingHttpHeaders;
+ };
+}
+export declare enum EApiV1ErrorCode {
+ InvalidCoordinates = 3,
+ NoLocationFound = 13,
+ AuthenticationFail = 32,
+ InvalidOrExpiredToken = 89,
+ UnableToVerifyCredentials = 99,
+ AuthTimestampInvalid = 135,
+ BadAuthenticationData = 215,
+ NoUserMatch = 17,
+ UserNotFound = 50,
+ ResourceNotFound = 34,
+ TweetNotFound = 144,
+ TweetNotVisible = 179,
+ NotAllowedResource = 220,
+ MediaIdNotFound = 325,
+ TweetNoLongerAvailable = 421,
+ TweetViolatedRules = 422,
+ TargetUserSuspended = 63,
+ YouAreSuspended = 64,
+ AccountUpdateFailed = 120,
+ NoSelfSpamReport = 36,
+ NoSelfMute = 271,
+ AccountLocked = 326,
+ RateLimitExceeded = 88,
+ NoDMRightForApp = 93,
+ OverCapacity = 130,
+ InternalError = 131,
+ TooManyFollowings = 161,
+ TweetLimitExceeded = 185,
+ DuplicatedTweet = 187,
+ TooManySpamReports = 205,
+ RequestLooksLikeSpam = 226,
+ NoWriteRightForApp = 261,
+ TweetActionsDisabled = 425,
+ TweetRepliesRestricted = 433,
+ NamedParameterMissing = 38,
+ InvalidAttachmentUrl = 44,
+ TweetTextTooLong = 186,
+ MissingUrlParameter = 195,
+ NoMultipleGifs = 323,
+ InvalidMediaIds = 324,
+ InvalidUrl = 407,
+ TooManyTweetAttachments = 386,
+ StatusAlreadyFavorited = 139,
+ FollowRequestAlreadySent = 160,
+ CannotUnmuteANonMutedAccount = 272,
+ TweetAlreadyRetweeted = 327,
+ ReplyToDeletedTweet = 385,
+ DMReceiverNotFollowingYou = 150,
+ UnableToSendDM = 151,
+ MustAllowDMFromAnyone = 214,
+ CannotSendDMToThisUser = 349,
+ DMTextTooLong = 354,
+ SubscriptionAlreadyExists = 355,
+ CallbackUrlNotApproved = 415,
+ SuspendedApplication = 416,
+ OobOauthIsNotAllowed = 417
+}
+export declare enum EApiV2ErrorCode {
+ InvalidRequest = "https://api.twitter.com/2/problems/invalid-request",
+ ClientForbidden = "https://api.twitter.com/2/problems/client-forbidden",
+ UnsupportedAuthentication = "https://api.twitter.com/2/problems/unsupported-authentication",
+ InvalidRules = "https://api.twitter.com/2/problems/invalid-rules",
+ TooManyRules = "https://api.twitter.com/2/problems/rule-cap",
+ DuplicatedRules = "https://api.twitter.com/2/problems/duplicate-rules",
+ RateLimitExceeded = "https://api.twitter.com/2/problems/usage-capped",
+ ConnectionError = "https://api.twitter.com/2/problems/streaming-connection",
+ ClientDisconnected = "https://api.twitter.com/2/problems/client-disconnected",
+ TwitterDisconnectedYou = "https://api.twitter.com/2/problems/operational-disconnect",
+ ResourceNotFound = "https://api.twitter.com/2/problems/resource-not-found",
+ ResourceUnauthorized = "https://api.twitter.com/2/problems/not-authorized-for-resource",
+ DisallowedResource = "https://api.twitter.com/2/problems/disallowed-resource"
+}
+export {};
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/errors.types.js b/node_modules/twitter-api-v2/dist/cjs/types/errors.types.js
new file mode 100644
index 0000000..00970f4
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/errors.types.js
@@ -0,0 +1,223 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.EApiV2ErrorCode = exports.EApiV1ErrorCode = exports.ApiResponseError = exports.ApiPartialResponseError = exports.ApiRequestError = exports.ETwitterApiError = void 0;
+var ETwitterApiError;
+(function (ETwitterApiError) {
+ ETwitterApiError["Request"] = "request";
+ ETwitterApiError["PartialResponse"] = "partial-response";
+ ETwitterApiError["Response"] = "response";
+})(ETwitterApiError = exports.ETwitterApiError || (exports.ETwitterApiError = {}));
+/* ERRORS INSTANCES */
+class ApiError extends Error {
+ constructor() {
+ super(...arguments);
+ this.error = true;
+ }
+}
+class ApiRequestError extends ApiError {
+ constructor(message, options) {
+ super(message);
+ this.type = ETwitterApiError.Request;
+ Error.captureStackTrace(this, this.constructor);
+ // Do not show on Node stack trace
+ Object.defineProperty(this, '_options', { value: options });
+ }
+ get request() {
+ return this._options.request;
+ }
+ get requestError() {
+ return this._options.requestError;
+ }
+ toJSON() {
+ return {
+ type: this.type,
+ error: this.requestError,
+ };
+ }
+}
+exports.ApiRequestError = ApiRequestError;
+class ApiPartialResponseError extends ApiError {
+ constructor(message, options) {
+ super(message);
+ this.type = ETwitterApiError.PartialResponse;
+ Error.captureStackTrace(this, this.constructor);
+ // Do not show on Node stack trace
+ Object.defineProperty(this, '_options', { value: options });
+ }
+ get request() {
+ return this._options.request;
+ }
+ get response() {
+ return this._options.response;
+ }
+ get responseError() {
+ return this._options.responseError;
+ }
+ get rawContent() {
+ return this._options.rawContent;
+ }
+ toJSON() {
+ return {
+ type: this.type,
+ error: this.responseError,
+ };
+ }
+}
+exports.ApiPartialResponseError = ApiPartialResponseError;
+class ApiResponseError extends ApiError {
+ constructor(message, options) {
+ super(message);
+ this.type = ETwitterApiError.Response;
+ Error.captureStackTrace(this, this.constructor);
+ // Do not show on Node stack trace
+ Object.defineProperty(this, '_options', { value: options });
+ this.code = options.code;
+ this.headers = options.headers;
+ this.rateLimit = options.rateLimit;
+ // Fix bad error data payload on some v1 endpoints (see https://github.com/PLhery/node-twitter-api-v2/issues/342)
+ if (options.data && typeof options.data === 'object' && 'error' in options.data && !options.data.errors) {
+ const data = { ...options.data };
+ data.errors = [{
+ code: EApiV1ErrorCode.InternalError,
+ message: data.error,
+ }];
+ this.data = data;
+ }
+ else {
+ this.data = options.data;
+ }
+ }
+ get request() {
+ return this._options.request;
+ }
+ get response() {
+ return this._options.response;
+ }
+ /** Check for presence of one of given v1/v2 error codes. */
+ hasErrorCode(...codes) {
+ const errors = this.errors;
+ // No errors
+ if (!(errors === null || errors === void 0 ? void 0 : errors.length)) {
+ return false;
+ }
+ // v1 errors
+ if ('code' in errors[0]) {
+ const v1errors = errors;
+ return v1errors.some(error => codes.includes(error.code));
+ }
+ // v2 error
+ const v2error = this.data;
+ return codes.includes(v2error.type);
+ }
+ get errors() {
+ var _a;
+ return (_a = this.data) === null || _a === void 0 ? void 0 : _a.errors;
+ }
+ get rateLimitError() {
+ return this.code === 420 || this.code === 429;
+ }
+ get isAuthError() {
+ if (this.code === 401) {
+ return true;
+ }
+ return this.hasErrorCode(EApiV1ErrorCode.AuthTimestampInvalid, EApiV1ErrorCode.AuthenticationFail, EApiV1ErrorCode.BadAuthenticationData, EApiV1ErrorCode.InvalidOrExpiredToken);
+ }
+ toJSON() {
+ return {
+ type: this.type,
+ code: this.code,
+ error: this.data,
+ rateLimit: this.rateLimit,
+ headers: this.headers,
+ };
+ }
+}
+exports.ApiResponseError = ApiResponseError;
+var EApiV1ErrorCode;
+(function (EApiV1ErrorCode) {
+ // Location errors
+ EApiV1ErrorCode[EApiV1ErrorCode["InvalidCoordinates"] = 3] = "InvalidCoordinates";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoLocationFound"] = 13] = "NoLocationFound";
+ // Authentication failures
+ EApiV1ErrorCode[EApiV1ErrorCode["AuthenticationFail"] = 32] = "AuthenticationFail";
+ EApiV1ErrorCode[EApiV1ErrorCode["InvalidOrExpiredToken"] = 89] = "InvalidOrExpiredToken";
+ EApiV1ErrorCode[EApiV1ErrorCode["UnableToVerifyCredentials"] = 99] = "UnableToVerifyCredentials";
+ EApiV1ErrorCode[EApiV1ErrorCode["AuthTimestampInvalid"] = 135] = "AuthTimestampInvalid";
+ EApiV1ErrorCode[EApiV1ErrorCode["BadAuthenticationData"] = 215] = "BadAuthenticationData";
+ // Resources not found or visible
+ EApiV1ErrorCode[EApiV1ErrorCode["NoUserMatch"] = 17] = "NoUserMatch";
+ EApiV1ErrorCode[EApiV1ErrorCode["UserNotFound"] = 50] = "UserNotFound";
+ EApiV1ErrorCode[EApiV1ErrorCode["ResourceNotFound"] = 34] = "ResourceNotFound";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetNotFound"] = 144] = "TweetNotFound";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetNotVisible"] = 179] = "TweetNotVisible";
+ EApiV1ErrorCode[EApiV1ErrorCode["NotAllowedResource"] = 220] = "NotAllowedResource";
+ EApiV1ErrorCode[EApiV1ErrorCode["MediaIdNotFound"] = 325] = "MediaIdNotFound";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetNoLongerAvailable"] = 421] = "TweetNoLongerAvailable";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetViolatedRules"] = 422] = "TweetViolatedRules";
+ // Account errors
+ EApiV1ErrorCode[EApiV1ErrorCode["TargetUserSuspended"] = 63] = "TargetUserSuspended";
+ EApiV1ErrorCode[EApiV1ErrorCode["YouAreSuspended"] = 64] = "YouAreSuspended";
+ EApiV1ErrorCode[EApiV1ErrorCode["AccountUpdateFailed"] = 120] = "AccountUpdateFailed";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoSelfSpamReport"] = 36] = "NoSelfSpamReport";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoSelfMute"] = 271] = "NoSelfMute";
+ EApiV1ErrorCode[EApiV1ErrorCode["AccountLocked"] = 326] = "AccountLocked";
+ // Application live errors / Twitter errors
+ EApiV1ErrorCode[EApiV1ErrorCode["RateLimitExceeded"] = 88] = "RateLimitExceeded";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoDMRightForApp"] = 93] = "NoDMRightForApp";
+ EApiV1ErrorCode[EApiV1ErrorCode["OverCapacity"] = 130] = "OverCapacity";
+ EApiV1ErrorCode[EApiV1ErrorCode["InternalError"] = 131] = "InternalError";
+ EApiV1ErrorCode[EApiV1ErrorCode["TooManyFollowings"] = 161] = "TooManyFollowings";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetLimitExceeded"] = 185] = "TweetLimitExceeded";
+ EApiV1ErrorCode[EApiV1ErrorCode["DuplicatedTweet"] = 187] = "DuplicatedTweet";
+ EApiV1ErrorCode[EApiV1ErrorCode["TooManySpamReports"] = 205] = "TooManySpamReports";
+ EApiV1ErrorCode[EApiV1ErrorCode["RequestLooksLikeSpam"] = 226] = "RequestLooksLikeSpam";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoWriteRightForApp"] = 261] = "NoWriteRightForApp";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetActionsDisabled"] = 425] = "TweetActionsDisabled";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetRepliesRestricted"] = 433] = "TweetRepliesRestricted";
+ // Invalid request parameters
+ EApiV1ErrorCode[EApiV1ErrorCode["NamedParameterMissing"] = 38] = "NamedParameterMissing";
+ EApiV1ErrorCode[EApiV1ErrorCode["InvalidAttachmentUrl"] = 44] = "InvalidAttachmentUrl";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetTextTooLong"] = 186] = "TweetTextTooLong";
+ EApiV1ErrorCode[EApiV1ErrorCode["MissingUrlParameter"] = 195] = "MissingUrlParameter";
+ EApiV1ErrorCode[EApiV1ErrorCode["NoMultipleGifs"] = 323] = "NoMultipleGifs";
+ EApiV1ErrorCode[EApiV1ErrorCode["InvalidMediaIds"] = 324] = "InvalidMediaIds";
+ EApiV1ErrorCode[EApiV1ErrorCode["InvalidUrl"] = 407] = "InvalidUrl";
+ EApiV1ErrorCode[EApiV1ErrorCode["TooManyTweetAttachments"] = 386] = "TooManyTweetAttachments";
+ // Already sent/deleted item
+ EApiV1ErrorCode[EApiV1ErrorCode["StatusAlreadyFavorited"] = 139] = "StatusAlreadyFavorited";
+ EApiV1ErrorCode[EApiV1ErrorCode["FollowRequestAlreadySent"] = 160] = "FollowRequestAlreadySent";
+ EApiV1ErrorCode[EApiV1ErrorCode["CannotUnmuteANonMutedAccount"] = 272] = "CannotUnmuteANonMutedAccount";
+ EApiV1ErrorCode[EApiV1ErrorCode["TweetAlreadyRetweeted"] = 327] = "TweetAlreadyRetweeted";
+ EApiV1ErrorCode[EApiV1ErrorCode["ReplyToDeletedTweet"] = 385] = "ReplyToDeletedTweet";
+ // DM Errors
+ EApiV1ErrorCode[EApiV1ErrorCode["DMReceiverNotFollowingYou"] = 150] = "DMReceiverNotFollowingYou";
+ EApiV1ErrorCode[EApiV1ErrorCode["UnableToSendDM"] = 151] = "UnableToSendDM";
+ EApiV1ErrorCode[EApiV1ErrorCode["MustAllowDMFromAnyone"] = 214] = "MustAllowDMFromAnyone";
+ EApiV1ErrorCode[EApiV1ErrorCode["CannotSendDMToThisUser"] = 349] = "CannotSendDMToThisUser";
+ EApiV1ErrorCode[EApiV1ErrorCode["DMTextTooLong"] = 354] = "DMTextTooLong";
+ // Application misconfiguration
+ EApiV1ErrorCode[EApiV1ErrorCode["SubscriptionAlreadyExists"] = 355] = "SubscriptionAlreadyExists";
+ EApiV1ErrorCode[EApiV1ErrorCode["CallbackUrlNotApproved"] = 415] = "CallbackUrlNotApproved";
+ EApiV1ErrorCode[EApiV1ErrorCode["SuspendedApplication"] = 416] = "SuspendedApplication";
+ EApiV1ErrorCode[EApiV1ErrorCode["OobOauthIsNotAllowed"] = 417] = "OobOauthIsNotAllowed";
+})(EApiV1ErrorCode = exports.EApiV1ErrorCode || (exports.EApiV1ErrorCode = {}));
+var EApiV2ErrorCode;
+(function (EApiV2ErrorCode) {
+ // Request errors
+ EApiV2ErrorCode["InvalidRequest"] = "https://api.twitter.com/2/problems/invalid-request";
+ EApiV2ErrorCode["ClientForbidden"] = "https://api.twitter.com/2/problems/client-forbidden";
+ EApiV2ErrorCode["UnsupportedAuthentication"] = "https://api.twitter.com/2/problems/unsupported-authentication";
+ // Stream rules errors
+ EApiV2ErrorCode["InvalidRules"] = "https://api.twitter.com/2/problems/invalid-rules";
+ EApiV2ErrorCode["TooManyRules"] = "https://api.twitter.com/2/problems/rule-cap";
+ EApiV2ErrorCode["DuplicatedRules"] = "https://api.twitter.com/2/problems/duplicate-rules";
+ // Twitter errors
+ EApiV2ErrorCode["RateLimitExceeded"] = "https://api.twitter.com/2/problems/usage-capped";
+ EApiV2ErrorCode["ConnectionError"] = "https://api.twitter.com/2/problems/streaming-connection";
+ EApiV2ErrorCode["ClientDisconnected"] = "https://api.twitter.com/2/problems/client-disconnected";
+ EApiV2ErrorCode["TwitterDisconnectedYou"] = "https://api.twitter.com/2/problems/operational-disconnect";
+ // Resource errors
+ EApiV2ErrorCode["ResourceNotFound"] = "https://api.twitter.com/2/problems/resource-not-found";
+ EApiV2ErrorCode["ResourceUnauthorized"] = "https://api.twitter.com/2/problems/not-authorized-for-resource";
+ EApiV2ErrorCode["DisallowedResource"] = "https://api.twitter.com/2/problems/disallowed-resource";
+})(EApiV2ErrorCode = exports.EApiV2ErrorCode || (exports.EApiV2ErrorCode = {}));
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/index.d.ts
new file mode 100644
index 0000000..cfc014a
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/index.d.ts
@@ -0,0 +1,8 @@
+export * from './v1';
+export * from './v2';
+export * from './errors.types';
+export * from './responses.types';
+export * from './client.types';
+export * from './auth.types';
+export * from './plugins';
+export { IGetHttpRequestArgs } from './request-maker.mixin.types';
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/index.js b/node_modules/twitter-api-v2/dist/cjs/types/index.js
new file mode 100644
index 0000000..c27d6e7
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/index.js
@@ -0,0 +1,23 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./v1"), exports);
+__exportStar(require("./v2"), exports);
+__exportStar(require("./errors.types"), exports);
+__exportStar(require("./responses.types"), exports);
+__exportStar(require("./client.types"), exports);
+__exportStar(require("./auth.types"), exports);
+__exportStar(require("./plugins"), exports);
diff --git a/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.d.ts
new file mode 100644
index 0000000..85ef5cc
--- /dev/null
+++ b/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.d.ts
@@ -0,0 +1,59 @@
+///
+import type { ClientRequestArgs } from 'http';
+import type { IGetHttpRequestArgs } from '../request-maker.mixin.types';
+import type { TwitterResponse } from '../responses.types';
+import type { IComputedHttpRequestArgs } from '../request-maker.mixin.types';
+import type { IOAuth2RequestTokenResult, RequestTokenResult } from '../auth.types';
+import type { PromiseOrType } from '../shared.types';
+import type { ApiResponseError, ApiRequestError, ApiPartialResponseError } from '../errors.types';
+import type { ClientRequestMaker } from '../../client-mixins/request-maker.mixin';
+export declare class TwitterApiPluginResponseOverride {
+ value: any;
+ constructor(value: any);
+}
+export interface ITwitterApiClientPlugin {
+ onBeforeRequestConfig?: TTwitterApiBeforeRequestConfigHook;
+ onBeforeRequest?: TTwitterApiBeforeRequestHook;
+ onAfterRequest?: TTwitterApiAfterRequestHook;
+ onRequestError?: TTwitterApiRequestErrorHook;
+ onResponseError?: TTwitterApiResponseErrorHook;
+ onBeforeStreamRequestConfig?: TTwitterApiBeforeStreamRequestConfigHook;
+ onOAuth1RequestToken?: TTwitterApiAfterOAuth1RequestTokenHook;
+ onOAuth2RequestToken?: TTwitterApiAfterOAuth2RequestTokenHook;
+}
+export interface ITwitterApiBeforeRequestConfigHookArgs {
+ client: ClientRequestMaker;
+ url: URL;
+ params: IGetHttpRequestArgs;
+}
+export interface ITwitterApiBeforeRequestHookArgs extends ITwitterApiBeforeRequestConfigHookArgs {
+ computedParams: IComputedHttpRequestArgs;
+ requestOptions: Partial;
+}
+export interface ITwitterApiAfterRequestHookArgs extends ITwitterApiBeforeRequestHookArgs {
+ response: TwitterResponse;
+}
+export interface ITwitterApiRequestErrorHookArgs extends ITwitterApiBeforeRequestHookArgs {
+ error: ApiRequestError | ApiPartialResponseError;
+}
+export interface ITwitterApiResponseErrorHookArgs extends ITwitterApiBeforeRequestHookArgs {
+ error: ApiResponseError;
+}
+export declare type TTwitterApiBeforeRequestConfigHook = (args: ITwitterApiBeforeRequestConfigHookArgs) => PromiseOrType | void>;
+export declare type TTwitterApiBeforeRequestHook = (args: ITwitterApiBeforeRequestHookArgs) => void | Promise;
+export declare type TTwitterApiAfterRequestHook = (args: ITwitterApiAfterRequestHookArgs) => PromiseOrType;
+export declare type TTwitterApiRequestErrorHook = (args: ITwitterApiRequestErrorHookArgs) => PromiseOrType