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 + +[![Twitter API v2 badge](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.twitter.com/en/docs/twitter-api/early-access) +[![Twitter API v1.1 badge](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fstandard)](https://developer.twitter.com/en/docs/twitter-api/v1) +[![Version badge](https://badgen.net/github/release/PLhery/node-twitter-api-v2)](https://github.com/PLhery/node-twitter-api-v2) +[![Checks badge](https://github.com/PLhery/node-twitter-api-v2/actions/workflows/CI.yml/badge.svg)](https://github.com/PLhery/node-twitter-api-v2/actions/workflows/CI.yml) +[![Package size badge](https://badgen.net/bundlephobia/minzip/twitter-api-v2)](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) - Buy Me A Coffee + +## 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 | [![twitter-api-v2 install size badge](https://badgen.net/packagephobia/install/twitter-api-v2)](https://packagephobia.com/result?p=twitter-api-v2) | +| twit | v1.1 | ❌ | ✅ | ❌ | 51 | ~214.5 kB | [![twit install size badge](https://badgen.net/packagephobia/install/twit)](https://packagephobia.com/result?p=twit) | +| twitter | v1.1 | ❌ | ❌ | ❌ | 50 | ~182.1 kB | [![twitter install size badge](https://badgen.net/packagephobia/install/twitter)](https://packagephobia.com/result?p=twitter) | +| twitter-lite | v1.1, v2 | ❌ | ❌ | ❌ | 4 | ~5.3 kB | [![twitter-lite install size badge](https://badgen.net/packagephobia/install/twitter-lite)](https://packagephobia.com/result?p=twitter-lite) | +| twitter-v2 | v2 | ❌ | ❌ | ❌ | 7 | ~4.5 kB | [![twitter-v2 install size badge](https://badgen.net/packagephobia/install/twitter-v2)](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; +export declare type TTwitterApiResponseErrorHook = (args: ITwitterApiResponseErrorHookArgs) => PromiseOrType; +export declare type TTwitterApiBeforeStreamRequestConfigHook = (args: ITwitterApiBeforeRequestConfigHookArgs) => void; +export interface ITwitterApiAfterOAuth1RequestTokenHookArgs { + client: ClientRequestMaker; + url: string; + oauthResult: RequestTokenResult; +} +export interface ITwitterApiAfterOAuth2RequestTokenHookArgs { + client: ClientRequestMaker; + result: IOAuth2RequestTokenResult; + redirectUri: string; +} +export declare type TTwitterApiAfterOAuth1RequestTokenHook = (args: ITwitterApiAfterOAuth1RequestTokenHookArgs) => void | Promise; +export declare type TTwitterApiAfterOAuth2RequestTokenHook = (args: ITwitterApiAfterOAuth2RequestTokenHookArgs) => void | Promise; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.js b/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.js new file mode 100644 index 0000000..f2e6f16 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/plugins/client.plugins.types.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TwitterApiPluginResponseOverride = void 0; +class TwitterApiPluginResponseOverride { + constructor(value) { + this.value = value; + } +} +exports.TwitterApiPluginResponseOverride = TwitterApiPluginResponseOverride; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.d.ts new file mode 100644 index 0000000..7459ee7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.d.ts @@ -0,0 +1 @@ +export * from './client.plugins.types'; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.js b/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.js new file mode 100644 index 0000000..d6e57a8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/plugins/index.js @@ -0,0 +1,17 @@ +"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("./client.plugins.types"), exports); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.types.d.ts new file mode 100644 index 0000000..8608561 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.types.d.ts @@ -0,0 +1,74 @@ +/// +/// +import type { RequestOptions } from 'https'; +import type { TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens } from './client.types'; +import type { TwitterRateLimit } from './responses.types'; +export declare type TRequestDebuggerHandlerEvent = 'abort' | 'close' | 'socket' | 'socket-error' | 'socket-connect' | 'socket-close' | 'socket-end' | 'socket-lookup' | 'socket-timeout' | 'request-error' | 'response' | 'response-aborted' | 'response-error' | 'response-close' | 'response-end'; +export declare type TRequestDebuggerHandler = (event: TRequestDebuggerHandlerEvent, data?: any) => void; +/** + * Request compression level. `true` means `'brotli'`, `false` means `'identity'`. + * When `brotli` is unavailable (f.e. in streams), it will fallback to `gzip`. + */ +export declare type TRequestCompressionLevel = boolean | 'brotli' | 'gzip' | 'deflate' | 'identity'; +export declare type TRequestFullData = { + url: URL; + options: RequestOptions; + body?: any; + rateLimitSaver?: (rateLimit: TwitterRateLimit) => any; + requestEventDebugHandler?: TRequestDebuggerHandler; + compression?: TRequestCompressionLevel; + forceParseMode?: TResponseParseMode; +}; +export declare type TRequestFullStreamData = TRequestFullData & { + payloadIsError?: (data: any) => boolean; +}; +export declare type TRequestQuery = Record; +export declare type TRequestStringQuery = Record; +export declare type TRequestBody = Record | Buffer; +export declare type TBodyMode = 'json' | 'url' | 'form-data' | 'raw'; +export declare type TResponseParseMode = 'json' | 'url' | 'text' | 'buffer' | 'none'; +export interface IWriteAuthHeadersArgs { + headers: Record; + bodyInSignature: boolean; + url: URL; + method: string; + query: TRequestQuery; + body: TRequestBody; +} +export interface IGetHttpRequestArgs { + url: string; + method: string; + query?: TRequestQuery; + /** The URL parameters, if you specify an endpoint with `:id`, for example. */ + params?: TRequestQuery; + body?: TRequestBody; + headers?: Record; + forceBodyMode?: TBodyMode; + forceParseMode?: TResponseParseMode; + enableAuth?: boolean; + enableRateLimitSave?: boolean; + timeout?: number; + requestEventDebugHandler?: TRequestDebuggerHandler; + compression?: TRequestCompressionLevel; +} +export interface IComputedHttpRequestArgs { + rawUrl: string; + url: URL; + method: string; + headers: Record; + body: string | Buffer | undefined; +} +export interface IGetStreamRequestArgs { + payloadIsError?: (data: any) => boolean; + autoConnect?: boolean; +} +export interface IGetStreamRequestArgsAsync { + payloadIsError?: (data: any) => boolean; + autoConnect?: true; +} +export interface IGetStreamRequestArgsSync { + payloadIsError?: (data: any) => boolean; + autoConnect: false; +} +export declare type TCustomizableRequestArgs = Pick; +export declare type TAcceptedInitToken = TwitterApiTokens | TwitterApiOAuth2Init | TwitterApiBasicAuth | string; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.types.js b/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/request-maker.mixin.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/responses.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/responses.types.d.ts new file mode 100644 index 0000000..2abfbb2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/responses.types.d.ts @@ -0,0 +1,12 @@ +/// +import type { IncomingHttpHeaders } from 'http'; +export interface TwitterResponse { + headers: IncomingHttpHeaders; + data: T; + rateLimit?: TwitterRateLimit; +} +export interface TwitterRateLimit { + limit: number; + reset: number; + remaining: number; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/responses.types.js b/node_modules/twitter-api-v2/dist/cjs/types/responses.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/responses.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/shared.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/shared.types.d.ts new file mode 100644 index 0000000..f0538d7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/shared.types.d.ts @@ -0,0 +1,4 @@ +export declare type NumberString = number | string; +export declare type BooleanString = boolean | string; +export declare type TypeOrArrayOf = T | T[]; +export declare type PromiseOrType = T | Promise; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/shared.types.js b/node_modules/twitter-api-v2/dist/cjs/types/shared.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/shared.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/v1/dev-utilities.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/dev-utilities.v1.types.d.ts new file mode 100644 index 0000000..8d89b69 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/dev-utilities.v1.types.d.ts @@ -0,0 +1,21 @@ +export declare type TAppRateLimitResourceV1 = 'help' | 'statuses' | 'friends' | 'followers' | 'users' | 'search' | 'trends' | 'favorites' | 'friendships' | 'direct_messages' | 'lists' | 'geo' | 'account' | 'application' | 'account_activity'; +export interface AppRateLimitV1Result { + rate_limit_context: { + access_token: string; + }; + resources: { + [TResourceName in TAppRateLimitResourceV1]?: { + [resourceEndpoint: string]: AppRateLimitEndpointV1; + }; + }; +} +export interface AppRateLimitEndpointV1 { + limit: number; + remaining: number; + reset: number; +} +export interface HelpLanguageV1Result { + code: string; + status: string; + name: string; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/dev-utilities.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/dev-utilities.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/dev-utilities.v1.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/v1/dm.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/dm.v1.types.d.ts new file mode 100644 index 0000000..c6aeb80 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/dm.v1.types.d.ts @@ -0,0 +1,162 @@ +import { CoordinateV1, MediaEntityV1, TweetEntitiesV1 } from './entities.v1.types'; +export declare enum EDirectMessageEventTypeV1 { + Create = "message_create", + WelcomeCreate = "welcome_message" +} +export interface MessageCreateEventV1 { + target: { + recipient_id: string; + }; + message_data: MessageCreateDataV1; + custom_profile_id?: string; +} +export interface MessageCreateDataV1 { + text: string; + attachment?: MessageCreateAttachmentV1; + quick_reply?: MessageCreateQuickReplyV1; + ctas?: MessageCreateCtaV1[]; +} +export interface MessageCreateCtaV1 { + type: 'web_url'; + url: string; + label: string; + /** Only when messages are retrieved from API */ + tco_url?: string; +} +export interface MessageCreateQuickReplyOptionV1 { + label: string; + description?: string; + metadata?: string; +} +export interface MessageCreateQuickReplyV1 { + type: 'options'; + options: MessageCreateQuickReplyOptionV1[]; +} +export declare type MessageCreateAttachmentV1 = { + type: 'media'; + media: { + id: string; + }; +} | { + type: 'location'; + location: MessageCreateLocationV1; +}; +export declare type MessageCreateLocationV1 = { + type: 'shared_coordinate'; + shared_coordinate: { + coordinates: CoordinateV1; + }; +} | { + type: 'shared_place'; + shared_place: { + place: { + id: string; + }; + }; +}; +export interface SendDMV1Params extends MessageCreateDataV1 { + recipient_id: string; + custom_profile_id?: string; +} +export interface CreateDMEventV1Args { + event: CreateDMEventV1; +} +export interface CreateDMEventV1 { + type: EDirectMessageEventTypeV1; + [EDirectMessageEventTypeV1.Create]?: MessageCreateEventV1; +} +export interface GetDmListV1Args { + cursor?: string; + count?: number; +} +export interface CreateWelcomeDMEventV1Args { + [EDirectMessageEventTypeV1.WelcomeCreate]: { + name: string; + message_data: MessageCreateDataV1; + }; +} +export interface DirectMessageCreateV1 extends ReceivedDirectMessageEventV1 { + type: EDirectMessageEventTypeV1.Create; + [EDirectMessageEventTypeV1.Create]: ReceivedMessageCreateEventV1; +} +export interface ReceivedDirectMessageEventV1 { + type: EDirectMessageEventTypeV1; + id: string; + created_timestamp: string; + initiated_via?: { + tweet_id?: string; + welcome_message_id?: string; + }; +} +export interface ReceivedMessageCreateEventV1 { + target: { + recipient_id: string; + }; + sender_id: string; + source_app_id: string; + message_data: ReceivedMessageCreateDataV1; + custom_profile_id?: string; +} +export interface ReceivedMessageCreateDataV1 { + text: string; + entities: TweetEntitiesV1; + quick_reply_response?: { + type: 'options'; + metadata?: string; + }; + attachment?: { + type: 'media'; + media: MediaEntityV1; + }; + quick_reply?: MessageCreateQuickReplyV1; + ctas?: MessageCreateCtaV1[]; +} +export interface ReceivedWelcomeDMCreateEventV1 { + id: string; + created_timestamp: string; + message_data: ReceivedMessageCreateDataV1; + name?: string; +} +export declare type DirectMessageCreateV1Result = { + event: DirectMessageCreateV1; +} & ReceivedDMAppsV1; +export interface ReceivedDMAppsV1 { + apps?: ReceivedDMAppListV1; +} +export declare type TReceivedDMEvent = DirectMessageCreateV1; +export interface ReceivedDMEventV1 extends ReceivedDMAppsV1 { + event: TReceivedDMEvent; +} +export interface ReceivedDMEventsV1 extends ReceivedDMAppsV1 { + next_cursor?: string; + events: TReceivedDMEvent[]; +} +export interface ReceivedDMAppListV1 { + [appId: string]: { + id: string; + name: string; + url: string; + }; +} +export interface WelcomeDirectMessageCreateV1Result extends ReceivedDMAppsV1 { + [EDirectMessageEventTypeV1.WelcomeCreate]: ReceivedWelcomeDMCreateEventV1; + name?: string; +} +export interface WelcomeDirectMessageListV1Result extends ReceivedDMAppsV1 { + next_cursor?: string; + welcome_messages: ReceivedWelcomeDMCreateEventV1[]; +} +export interface CreateWelcomeDmRuleV1 { + welcome_message_id: string; +} +export interface WelcomeDmRuleV1 extends CreateWelcomeDmRuleV1 { + id: string; + created_timestamp: string; +} +export interface WelcomeDmRuleV1Result { + welcome_message_rule: WelcomeDmRuleV1; +} +export interface WelcomeDmRuleListV1Result { + next_cursor?: string; + welcome_message_rules?: WelcomeDmRuleV1[]; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/dm.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/dm.v1.types.js new file mode 100644 index 0000000..eeb9fca --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/dm.v1.types.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EDirectMessageEventTypeV1 = void 0; +// Creation of DMs +var EDirectMessageEventTypeV1; +(function (EDirectMessageEventTypeV1) { + EDirectMessageEventTypeV1["Create"] = "message_create"; + EDirectMessageEventTypeV1["WelcomeCreate"] = "welcome_message"; +})(EDirectMessageEventTypeV1 = exports.EDirectMessageEventTypeV1 || (exports.EDirectMessageEventTypeV1 = {})); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.types.d.ts new file mode 100644 index 0000000..3f28838 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.types.d.ts @@ -0,0 +1,142 @@ +export interface TweetEntitiesV1 { + hashtags?: HashtagEntityV1[]; + urls?: UrlEntityV1[]; + user_mentions?: MentionEntityV1[]; + symbols?: SymbolEntityV1[]; + media?: MediaEntityV1[]; + polls?: [PollEntityV1]; +} +export interface TweetExtendedEntitiesV1 { + media?: MediaEntityV1[]; +} +export interface UserEntitiesV1 { + url?: { + urls: UrlEntityV1[]; + }; + description?: { + urls: UrlEntityV1[]; + }; +} +export interface UrlEntityV1 { + display_url: string; + expanded_url: string; + indices: [number, number]; + url: string; + unwound?: { + url: string; + status: number; + title: string; + description: string; + }; +} +export interface MediaEntityV1 { + display_url: string; + expanded_url: string; + url: string; + id: number; + id_str: string; + indices: [number, number]; + media_url: string; + media_url_https: string; + sizes: MediaSizesV1; + source_status_id: number; + source_status_id_str: string; + source_user_id: number; + source_user_id_str: string; + type: 'photo' | 'video' | 'animated_gif'; + video_info?: MediaVideoInfoV1; + additional_media_info?: AdditionalMediaInfoV1; + ext_alt_text?: string; +} +export interface MediaVideoInfoV1 { + aspect_ratio: [number, number]; + duration_millis: number; + variants: { + bitrate: number; + content_type: string; + url: string; + }[]; +} +export interface AdditionalMediaInfoV1 { + title: string; + description: string; + embeddable: boolean; + monetizable: boolean; +} +export interface MediaSizesV1 { + thumb: MediaSizeObjectV1; + large: MediaSizeObjectV1; + medium: MediaSizeObjectV1; + small: MediaSizeObjectV1; +} +export interface MediaSizeObjectV1 { + w: number; + h: number; + resize: 'crop' | 'fit'; +} +export interface HashtagEntityV1 { + indices: [number, number]; + text: string; +} +export interface MentionEntityV1 { + id: number; + id_str: string; + indices: [number, number]; + name: string; + screen_name: string; +} +export interface SymbolEntityV1 { + indices: [number, number]; + text: string; +} +export interface PollEntityV1 { + options: PollPositionV1[]; + end_datetime: string; + duration_minutes: number; +} +export interface PollPositionV1 { + position: number; + text: string; +} +/** See GeoJSON. */ +export interface CoordinateV1 { + coordinates: number[] | number[][]; + type: string; +} +export interface PlaceV1 { + full_name: string; + id: string; + url: string; + country: string; + country_code: string; + bounding_box: CoordinateV1; + name: string; + place_type: string; + contained_within?: PlaceV1[]; + geometry?: any; + polylines?: number[]; + centroid?: number[]; + attributes?: { + geotagCount: string; + [geoTagId: string]: string; + }; +} +export interface TrendV1 { + name: string; + url: string; + promoted_content?: boolean; + query: string; + tweet_volume: number; +} +export interface TrendLocationV1 { + name: string; + woeid: number; + url?: string; + placeType?: { + code: number; + name: string; + }; + parentid?: number; + country?: string; + countryCode?: string; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/entities.v1.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/v1/geo.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/geo.v1.types.d.ts new file mode 100644 index 0000000..658f149 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/geo.v1.types.d.ts @@ -0,0 +1,32 @@ +import { PlaceV1 } from './entities.v1.types'; +export interface ReverseGeoCodeV1Params { + lat: number; + long: number; + accuracy?: string; + granularity?: 'city' | 'neighborhood' | 'country' | 'admin'; + max_results?: number; +} +export interface ReverseGeoCodeV1Result { + query: { + params: Partial; + type: string; + url: string; + }; + result: { + places: PlaceV1[]; + }; +} +export interface SearchGeoV1Params extends Partial { + ip?: string; + query?: string; +} +export interface SearchGeoV1Result { + query: { + params: SearchGeoV1Params; + type: string; + url: string; + }; + result: { + places: PlaceV1[]; + }; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/geo.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/geo.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/geo.v1.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/v1/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/index.d.ts new file mode 100644 index 0000000..51d26b8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/index.d.ts @@ -0,0 +1,9 @@ +export * from './streaming.v1.types'; +export * from './tweet.v1.types'; +export * from './entities.v1.types'; +export * from './user.v1.types'; +export * from './dev-utilities.v1.types'; +export * from './geo.v1.types'; +export * from './trends.v1.types'; +export * from './dm.v1.types'; +export * from './list.v1.types'; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/index.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/index.js new file mode 100644 index 0000000..eeb44ed --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/index.js @@ -0,0 +1,25 @@ +"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("./streaming.v1.types"), exports); +__exportStar(require("./tweet.v1.types"), exports); +__exportStar(require("./entities.v1.types"), exports); +__exportStar(require("./user.v1.types"), exports); +__exportStar(require("./dev-utilities.v1.types"), exports); +__exportStar(require("./geo.v1.types"), exports); +__exportStar(require("./trends.v1.types"), exports); +__exportStar(require("./dm.v1.types"), exports); +__exportStar(require("./list.v1.types"), exports); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.types.d.ts new file mode 100644 index 0000000..bf43789 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.types.d.ts @@ -0,0 +1,87 @@ +import { TweetV1TimelineParams } from './tweet.v1.types'; +import { UserV1 } from './user.v1.types'; +export interface ListV1 { + id: number; + id_str: string; + slug: string; + name: string; + full_name: string; + created_at: string; + description: string; + uri: string; + subscriber_count: number; + member_count: number; + mode: 'public' | 'private'; + user: UserV1; +} +declare type TUserOrScreenName = { + user_id: string; +} | { + screen_name: string; +}; +export declare type ListListsV1Params = Partial & { + reverse?: boolean; +}; +export interface GetListV1Params { + list_id?: string; + slug?: string; + owner_screen_name?: string; + owner_id?: string; +} +export interface ListMemberShowV1Params extends GetListV1Params { + include_entities?: boolean; + skip_status?: boolean; + user_id?: string; + screen_name?: string; + tweet_mode?: 'compat' | 'extended'; +} +export interface ListMembersV1Params extends GetListV1Params { + count?: number; + cursor?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'compat' | 'extended'; +} +export interface ListOwnershipsV1Params { + user_id?: string; + screen_name?: string; + count?: number; + cursor?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'compat' | 'extended'; +} +export declare type ListSubscriptionsV1Params = ListOwnershipsV1Params; +export interface ListMembershipsV1Params extends ListOwnershipsV1Params { + filter_to_owned_lists?: boolean; +} +export interface ListStatusesV1Params extends TweetV1TimelineParams, GetListV1Params { + include_rts?: boolean; +} +export interface ListCreateV1Params { + name: string; + mode?: 'public' | 'private'; + description?: string; + tweet_mode?: 'compat' | 'extended'; +} +export interface AddOrRemoveListMembersV1Params extends GetListV1Params { + user_id?: string | string[]; + screen_name?: string | string[]; +} +export interface UpdateListV1Params extends Partial, GetListV1Params { +} +export interface DoubleEndedListsCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + lists: ListV1[]; +} +export interface DoubleEndedUsersCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/list.v1.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/v1/streaming.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/streaming.v1.types.d.ts new file mode 100644 index 0000000..1a928a6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/streaming.v1.types.d.ts @@ -0,0 +1,27 @@ +import type { TypeOrArrayOf } from '../shared.types'; +export interface AskTweetStreamV1Params { + tweet_mode?: 'extended' | 'compat'; + /** Specifies whether stall warnings should be delivered. */ + stall_warnings: boolean; +} +/** + * See https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/guides/basic-stream-parameters + * for detailed documentation. + */ +export interface FilterStreamV1Params extends AskTweetStreamV1Params { + /** A list of user IDs, indicating the users to return statuses for in the stream. */ + follow: TypeOrArrayOf<(string | BigInt)>; + /** Keywords to track. */ + track: TypeOrArrayOf; + /** Specifies a set of bounding boxes to track. */ + locations: TypeOrArrayOf<{ + lng: string; + lat: string; + }>; + /** Specifies whether stall warnings should be delivered. */ + stall_warnings: boolean; + [otherParameter: string]: any; +} +export interface SampleStreamV1Params extends AskTweetStreamV1Params { + [otherParameter: string]: any; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/streaming.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/streaming.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/streaming.v1.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/v1/trends.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/trends.v1.types.d.ts new file mode 100644 index 0000000..7d4f61a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/trends.v1.types.d.ts @@ -0,0 +1,10 @@ +import { TrendLocationV1, TrendV1 } from './entities.v1.types'; +export interface TrendsPlaceV1Params { + exclude: string; +} +export interface TrendMatchV1 { + trends: TrendV1[]; + as_of: string; + created_at: string; + locations: TrendLocationV1[]; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/trends.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/trends.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/trends.v1.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/v1/tweet.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/tweet.v1.types.d.ts new file mode 100644 index 0000000..48815d7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/tweet.v1.types.d.ts @@ -0,0 +1,201 @@ +/// +/// +import type * as fs from 'fs'; +import type { BooleanString, NumberString } from '../shared.types'; +import { CoordinateV1, PlaceV1, TweetEntitiesV1, TweetExtendedEntitiesV1 } from './entities.v1.types'; +import { UserV1 } from './user.v1.types'; +export interface TweetV1 { + created_at: string; + id: number; + id_str: string; + text: string; + full_text?: string; + source: string; + truncated: boolean; + in_reply_to_status_id: number | null; + in_reply_to_status_id_str: string | null; + in_reply_to_user_id: number | null; + in_reply_to_user_id_str: string | null; + in_reply_to_screen_name: string | null; + user: UserV1; + coordinates: CoordinateV1 | null; + place: PlaceV1 | null; + quoted_status_id: number; + quoted_status_id_str: string; + is_quote_status: boolean; + quoted_status?: TweetV1; + retweeted_status?: TweetV1; + quote_count?: number; + reply_count?: number; + retweet_count: number; + favorite_count: number; + entities: TweetEntitiesV1; + extended_entities?: TweetExtendedEntitiesV1; + favorited: boolean | null; + retweeted: boolean; + possibly_sensitive: boolean | null; + filter_level: 'none' | 'low' | 'medium' | 'high'; + lang: string; + display_text_range?: [number, number]; + current_user_retweet?: { + id: number; + id_str: string; + }; + withheld_copyright?: boolean; + withheld_in_countries?: string[]; + withheld_scope?: string; + card_uri?: string; +} +export interface TweetShowV1Params { + tweet_mode?: 'compat' | 'extended'; + id?: string; + trim_user?: boolean; + include_my_retweet?: boolean; + include_entities?: boolean; + include_ext_alt_text?: boolean; + include_card_uri?: boolean; +} +export declare type TweetLookupV1Params = { + id?: string | string[]; + map?: boolean; +} & Omit; +export declare type TweetLookupNoMapV1Params = TweetLookupV1Params & { + map?: false; +}; +export declare type TweetLookupMapV1Params = TweetLookupV1Params & { + map: true; +}; +export interface AskTweetV1Params { + tweet_mode?: 'extended' | 'compat'; + include_entities?: boolean; + trim_user?: boolean; +} +export interface TweetV1TimelineParams extends AskTweetV1Params { + count?: number; + since_id?: string; + max_id?: string; + exclude_replies?: boolean; +} +export interface TweetV1UserTimelineParams extends TweetV1TimelineParams { + user_id?: string; + screen_name?: string; + include_rts?: boolean; +} +export interface SendTweetV1Params extends AskTweetV1Params { + status: string; + in_reply_to_status_id?: string; + auto_populate_reply_metadata?: BooleanString; + exclude_reply_user_ids?: string; + attachment_url?: string; + media_ids?: string | string[]; + possibly_sensitive?: BooleanString; + lat?: NumberString; + long?: NumberString; + display_coordinates?: BooleanString; + enable_dmcommands?: BooleanString; + fail_dmcommands?: BooleanString; + card_uri?: string; + place_id?: string; +} +export declare type TUploadTypeV1 = 'mp4' | 'longmp4' | 'mov' | 'gif' | 'jpg' | 'png' | 'srt' | 'webp'; +export declare enum EUploadMimeType { + Jpeg = "image/jpeg", + Mp4 = "video/mp4", + Mov = "video/quicktime", + Gif = "image/gif", + Png = "image/png", + Srt = "text/plain", + Webp = "image/webp" +} +export interface UploadMediaV1Params { + /** @deprecated Directly use `mimeType` parameter with one of the allowed MIME types in `EUploadMimeType`. */ + type: TUploadTypeV1 | string; + mimeType: EUploadMimeType | string; + target: 'tweet' | 'dm'; + chunkLength: number; + shared: boolean; + longVideo: boolean; + additionalOwners: string | string[]; + maxConcurrentUploads: number; +} +export interface MediaMetadataV1Params { + alt_text?: { + text: string; + }; +} +export interface MediaSubtitleV1Param { + media_id: string; + language_code: string; + display_name: string; +} +/** + * Link to a file that is usable as media. + * - `string`: File path + * - `Buffer`: File content, as binary buffer + * - `fs.promises.FileHandle`: Opened file with `fs.promises` + * - `number`: Opened file with `fs` classic functions + */ +export declare type TUploadableMedia = string | Buffer | fs.promises.FileHandle | number; +export interface OembedTweetV1Params { + url: string; + maxwidth?: number; + hide_media?: boolean; + hide_thread?: boolean; + omit_script?: boolean; + align?: 'left' | 'right' | 'center' | 'none'; + related?: string; + lang?: string; + theme?: 'light' | 'dark'; + link_color?: string; + widget_type?: 'video'; + dnt?: boolean; +} +export declare type TweetV1TimelineResult = TweetV1[]; +export interface InitMediaV1Result { + media_id: number; + media_id_string: string; + size: number; + expires_after_secs: number; + image: { + image_type: string; + w: number; + h: number; + }; +} +export interface MediaStatusV1Result { + media_id: number; + media_id_string: string; + size: number; + expires_after_secs: number; + video?: { + video_type: string; + }; + processing_info?: { + state: 'pending' | 'failed' | 'succeeded' | 'in_progress'; + check_after_secs?: number; + progress_percent?: number; + error?: { + code: number; + name: string; + message: string; + }; + }; +} +export interface OembedTweetV1Result { + url: string; + author_name: string; + author_url: string; + html: string; + width: number; + height: number | null; + type: string; + cache_age: string; + provider_name: string; + provider_url: string; + version: string; +} +export interface TweetLookupMapV1Result { + id: { + [tweetId: string]: TweetV1 | null; + }; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/tweet.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/tweet.v1.types.js new file mode 100644 index 0000000..fb8c1ac --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/tweet.v1.types.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EUploadMimeType = void 0; +var EUploadMimeType; +(function (EUploadMimeType) { + EUploadMimeType["Jpeg"] = "image/jpeg"; + EUploadMimeType["Mp4"] = "video/mp4"; + EUploadMimeType["Mov"] = "video/quicktime"; + EUploadMimeType["Gif"] = "image/gif"; + EUploadMimeType["Png"] = "image/png"; + EUploadMimeType["Srt"] = "text/plain"; + EUploadMimeType["Webp"] = "image/webp"; +})(EUploadMimeType = exports.EUploadMimeType || (exports.EUploadMimeType = {})); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.types.d.ts new file mode 100644 index 0000000..3d42368 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.types.d.ts @@ -0,0 +1,262 @@ +import { UserEntitiesV1 } from './entities.v1.types'; +import { TweetV1 } from './tweet.v1.types'; +export interface UserV1 { + id_str: string; + id: number; + name: string; + screen_name: string; + location: string; + derived?: any; + url: string | null; + description: string | null; + protected: boolean; + verified: boolean; + followers_count: number; + friends_count: number; + listed_count: number; + favourites_count: number; + statuses_count: number; + created_at: string; + profile_banner_url: string; + profile_image_url_https: string; + default_profile: boolean; + default_profile_image: boolean; + withheld_in_countries: string[]; + withheld_scope: string; + entities?: UserEntitiesV1; + /** Only on account/verify_credentials with include_email: true */ + email?: string; +} +declare type TUserIdOrScreenName = { + user_id: string; +} | { + screen_name: string; +}; +declare type TUserObjectParams = { + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'extended' | 'compat'; +}; +export interface DoubleEndedIdCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + ids: string[]; +} +export interface DoubleEndedIdCursorV1Params { + stringify_ids?: boolean; + cursor?: string; +} +export interface UserFollowingsIdsV1Params extends DoubleEndedIdCursorV1Params { + screen_name?: string; + user_id?: string; + count?: number; +} +export interface UserFollowerIdsV1Params extends DoubleEndedIdCursorV1Params { + screen_name?: string; + user_id?: string; + count?: number; +} +interface UserListV1Params { + screen_name?: string; + user_id?: string; + count?: number; + cursor?: string; + skip_status?: boolean; + include_user_entities: boolean; +} +export declare type UserFollowerListV1Params = UserListV1Params; +export declare type UserFriendListV1Params = UserListV1Params; +export interface VerifyCredentialsV1Params { + include_entities?: boolean; + skip_status?: boolean; + include_email?: boolean; +} +export interface MuteUserListV1Params { + cursor?: string; + include_entities?: boolean; + skip_status?: string; + tweet_mode?: 'extended'; +} +export declare type MuteUserIdsV1Params = DoubleEndedIdCursorV1Params; +export interface ReportSpamV1Params { + screen_name?: string; + user_id?: string; + perform_block?: boolean; +} +export interface UserSearchV1Params { + q?: string; + page?: number; + count?: number; + include_entities?: boolean; + tweet_mode?: 'extended'; +} +export interface AccountSettingsV1Params { + sleep_time_enabled?: boolean; + start_sleep_time?: number; + end_sleep_time?: number; + time_zone?: string; + trend_location_woeid?: number; + lang?: string; +} +export interface AccountProfileV1Params { + name?: string; + url?: string; + location?: string; + description?: string; + profile_link_color?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'extended'; +} +export declare type ProfileBannerSizeV1Params = TUserIdOrScreenName; +export interface ProfileBannerUpdateV1Params { + width?: number; + height?: number; + offset_left?: number; + offset_top?: number; +} +export declare type ProfileImageUpdateV1Params = TUserObjectParams; +export interface FriendshipShowV1Params { + source_id?: string; + source_screen_name?: string; + target_id?: string; + target_screen_name?: string; +} +export interface FriendshipLookupV1Params { + screen_name?: string | string[]; + user_id?: string | string[]; +} +export declare type FriendshipsIncomingV1Params = DoubleEndedIdCursorV1Params; +export interface FriendshipUpdateV1Params { + screen_name?: string; + user_id?: string; + device?: boolean; + retweets?: boolean; +} +export interface FriendshipCreateV1Params { + screen_name?: string; + user_id?: string; + follow?: boolean; +} +export interface FriendshipDestroyV1Params { + screen_name?: string; + user_id?: string; +} +export declare type UserShowV1Params = TUserIdOrScreenName & TUserObjectParams; +export declare type UserLookupV1Params = { + user_id?: string | string[]; + screen_name?: string | string[]; +} & TUserObjectParams; +export interface MuteUserListV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export declare type MuteUserIdsV1Result = DoubleEndedIdCursorV1Result; +export declare type UserFollowerIdsV1Result = DoubleEndedIdCursorV1Result; +export declare type UserFollowingIdsV1Result = DoubleEndedIdCursorV1Result; +interface UserListV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export declare type UserFollowerListV1Result = UserListV1Result; +export declare type UserFriendListV1Result = UserListV1Result; +export interface BannerSizeV1 { + h: number; + w: number; + url: string; +} +export interface ProfileBannerSizeV1 { + sizes: { + ipad: BannerSizeV1; + ipad_retina: BannerSizeV1; + web: BannerSizeV1; + web_retina: BannerSizeV1; + mobile: BannerSizeV1; + mobile_retina: BannerSizeV1; + '300x100': BannerSizeV1; + '600x200': BannerSizeV1; + '1500x500': BannerSizeV1; + }; +} +export interface AccountSettingsV1 { + time_zone: { + name: string; + utc_offset: number; + tzinfo_name: string; + }; + protected: boolean; + screen_name: string; + always_use_https: boolean; + use_cookie_personalization: boolean; + sleep_time: { + enabled: boolean; + end_time: string | null; + start_time: string | null; + }; + geo_enabled: boolean; + language: string; + discoverable_by_email: boolean; + discoverable_by_mobile_phone: boolean; + display_sensitive_media: boolean; + allow_contributor_request: 'all' | 'following' | string; + allow_dms_from: 'all' | 'following' | string; + allow_dm_groups_from: 'all' | 'following' | string; + translator_type: string; + trend_location: { + name: string; + countryCode: string; + url: string; + woeid: number; + placeType: { + name: string; + code: number; + }; + parentid: number | null; + country: string; + }[]; +} +export declare type TFriendshipConnectionV1 = 'following' | 'following_requested' | 'followed_by' | 'none' | 'blocking' | 'muting'; +export interface FriendshipRelationObjectV1 { + id: number; + id_str: string; + screen_name: string; + following: boolean; + followed_by: boolean; + live_following?: boolean; + following_received: boolean | null; + following_requested: boolean | null; + notifications_enabled?: boolean | null; + can_dm?: boolean | null; + blocking?: boolean | null; + blocked_by?: boolean | null; + muting?: boolean | null; + want_retweets?: boolean | null; + all_replies?: boolean | null; + marked_spam?: boolean | null; +} +export interface FriendshipV1 { + relationship: { + source: FriendshipRelationObjectV1; + target: FriendshipRelationObjectV1; + }; +} +export interface FriendshipCreateOrDestroyV1 extends UserV1 { + status: TweetV1; +} +export interface FriendshipLookupV1 { + name: string; + screen_name: string; + id: number; + id_str: string; + connections: TFriendshipConnectionV1[]; +} +export declare type FriendshipsIncomingV1Result = DoubleEndedIdCursorV1Result; +export {}; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v1/user.v1.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/v2/dm.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/dm.v2.types.d.ts new file mode 100644 index 0000000..d45cb8c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/dm.v2.types.d.ts @@ -0,0 +1,50 @@ +import { TypeOrArrayOf } from '../shared.types'; +import { TTweetv2MediaField, TTweetv2TweetField, TTweetv2UserField } from './tweet.v2.types'; +import { ApiV2Includes, ReferencedTweetV2 } from './tweet.definition.v2'; +import { DataMetaAndIncludeV2, PaginableCountMetaV2 } from './shared.v2.types'; +export declare type TDMEventV2Field = 'created_at' | 'follower_count' | 'member_count' | 'private' | 'description' | 'owner_id'; +export declare type TDMEventV2Expansion = 'attachments.media_keys' | 'referenced_tweets.id' | 'sender_id' | 'participant_ids'; +export declare type TDMEventV2EventType = 'MessageCreate' | 'ParticipantsJoin' | 'ParticipantsLeave'; +export interface GetDMEventV2Params { + 'dm_event.fields': TypeOrArrayOf | string; + event_types: TypeOrArrayOf | string; + expansions: TypeOrArrayOf | string; + max_results: number; + 'media.fields': TypeOrArrayOf | string; + pagination_token: string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export declare type GetDMEventV2Result = DataMetaAndIncludeV2; +export interface PostDMInConversationParams { + attachments?: [{ + media_id: string; + }]; + text?: string; +} +export interface CreateDMConversationParams { + conversation_type: 'Group'; + participant_ids: string[]; + message: PostDMInConversationParams; +} +export interface PostDMInConversationResult { + dm_conversation_id: string; + dm_event_id: string; +} +export interface BaseDMEventV2 { + id: string; + created_at?: string; + sender_id?: string; + dm_conversation_id?: string; + attachments?: DMEventAttachmentV2; + referenced_tweets?: ReferencedTweetV2[]; +} +export interface DMEventAttachmentV2 { + media_keys: string[]; +} +export declare type DMEventV2 = ({ + event_type: 'MessageCreate'; + text: string; +} & BaseDMEventV2) | ({ + event_type: Extract; +} & BaseDMEventV2); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/dm.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/dm.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/dm.v2.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/v2/index.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/index.d.ts new file mode 100644 index 0000000..c3d2677 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/index.d.ts @@ -0,0 +1,6 @@ +export * from './streaming.v2.types'; +export * from './tweet.v2.types'; +export * from './tweet.definition.v2'; +export * from './user.v2.types'; +export * from './spaces.v2.types'; +export * from './list.v2.types'; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/index.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/index.js new file mode 100644 index 0000000..bfb47d2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/index.js @@ -0,0 +1,22 @@ +"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("./streaming.v2.types"), exports); +__exportStar(require("./tweet.v2.types"), exports); +__exportStar(require("./tweet.definition.v2"), exports); +__exportStar(require("./user.v2.types"), exports); +__exportStar(require("./spaces.v2.types"), exports); +__exportStar(require("./list.v2.types"), exports); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.types.d.ts new file mode 100644 index 0000000..bd51fd0 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.types.d.ts @@ -0,0 +1,57 @@ +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2, DataV2, PaginableCountMetaV2 } from './shared.v2.types'; +import type { TTweetv2UserField } from './tweet.v2.types'; +import type { UserV2 } from './user.v2.types'; +export declare type TListV2Field = 'created_at' | 'follower_count' | 'member_count' | 'private' | 'description' | 'owner_id'; +export declare type TListV2Expansion = 'owner_id'; +export declare type TListV2Includes = { + users?: UserV2[]; +}; +export interface ListV2 { + id: string; + name: string; + created_at?: string; + private?: boolean; + follower_count?: number; + member_count?: number; + owner_id?: string; + description?: string; +} +export interface ListCreateV2Params { + name: string; + description?: string; + private?: boolean; +} +export interface GetListV2Params { + expansions: TypeOrArrayOf | string; + 'list.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface GetListTimelineV2Params extends Partial { + max_results?: number; + pagination_token?: string; +} +export declare type ListGetV2Result = DataAndIncludeV2; +export declare type ListTimelineV2Result = DataMetaAndIncludeV2; +export declare type ListCreateV2Result = DataV2<{ + id: string; + name: string; +}>; +export declare type ListUpdateV2Params = Omit & { + name?: string; +}; +export declare type ListUpdateV2Result = DataV2<{ + updated: true; +}>; +export declare type ListDeleteV2Result = DataV2<{ + deleted: true; +}>; +export declare type ListMemberV2Result = DataV2<{ + is_member: boolean; +}>; +export declare type ListFollowV2Result = DataV2<{ + following: boolean; +}>; +export declare type ListPinV2Result = DataV2<{ + pinned: boolean; +}>; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/list.v2.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/v2/shared.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/shared.v2.types.d.ts new file mode 100644 index 0000000..daa80b6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/shared.v2.types.d.ts @@ -0,0 +1,38 @@ +import type { InlineErrorV2 } from '../errors.types'; +export declare type MetaV2 = { + meta: M; + errors?: InlineErrorV2[]; +}; +export declare type DataV2 = { + data: D; + errors?: InlineErrorV2[]; +}; +export declare type IncludeV2 = { + includes?: I; + errors?: InlineErrorV2[]; +}; +export declare type DataAndMetaV2 = { + data: D; + meta: M; + errors?: InlineErrorV2[]; +}; +export declare type DataAndIncludeV2 = { + data: D; + includes?: I; + errors?: InlineErrorV2[]; +}; +export declare type DataMetaAndIncludeV2 = { + data: D; + meta: M; + includes?: I; + errors?: InlineErrorV2[]; +}; +export interface SentMeta { + /** The time when the request body was returned. */ + sent: string; +} +export interface PaginableCountMetaV2 { + result_count: number; + next_token?: string; + previous_token?: string; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/shared.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/shared.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/shared.v2.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/v2/spaces.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/spaces.v2.types.d.ts new file mode 100644 index 0000000..2518599 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/spaces.v2.types.d.ts @@ -0,0 +1,50 @@ +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2 } from './shared.v2.types'; +import type { TTweetv2UserField } from './tweet.v2.types'; +import type { UsersV2Params, UsersV2Result, UserV2 } from './user.v2.types'; +export interface SpaceV2FieldsParams { + expansions: TypeOrArrayOf | string; + 'space.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export declare type TSpaceV2Expansion = 'invited_user_ids' | 'speaker_ids' | 'creator_id' | 'host_ids'; +export declare type TSpaceV2SpaceField = 'host_ids' | 'created_at' | 'creator_id' | 'id' | 'lang' | 'invited_user_ids' | 'participant_count' | 'speaker_ids' | 'started_at' | 'state' | 'title' | 'updated_at' | 'scheduled_start' | 'is_ticketed' | 'topic_ids' | 'ended_at' | 'subscriber_count'; +export declare type TSpaceV2State = 'live' | 'scheduled'; +export interface SpaceV2CreatorLookupParams extends SpaceV2FieldsParams { + max_results?: number; +} +export interface SpaceV2SearchParams extends Partial { + query: string; + state: TSpaceV2State; + max_results?: number; +} +export interface SpaceV2BuyersParams extends Partial { +} +declare type SpaceV2Includes = { + users?: UserV2[]; +}; +export declare type SpaceV2SingleResult = DataAndIncludeV2; +export declare type SpaceV2LookupResult = DataMetaAndIncludeV2; +export declare type SpaceV2BuyersResult = UsersV2Result; +export interface SpaceV2 { + id: string; + state: TSpaceV2State; + created_at?: string; + host_ids?: string[]; + lang?: string; + is_ticketed?: boolean; + invited_user_ids?: string[]; + participant_count?: number; + scheduled_start?: string; + speaker_ids?: string[]; + started_at?: string; + title?: string; + creator_id?: string; + updated_at?: string; + topic_ids?: string[]; + ended_at?: string; + subscriber_count?: number; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/spaces.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/spaces.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/spaces.v2.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/v2/streaming.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/streaming.v2.types.d.ts new file mode 100644 index 0000000..d6d9682 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/streaming.v2.types.d.ts @@ -0,0 +1,63 @@ +import { DataAndMetaV2, MetaV2, SentMeta } from './shared.v2.types'; +export interface StreamingV2GetRulesParams { + /** Comma-separated list of rule IDs. If omitted, all rules are returned. */ + ids: string; +} +export interface StreamingV2Rule { + /** Unique identifier of this rule. */ + id: string; + /** The rule text as submitted when creating the rule. */ + value: string; + /** The tag label as defined when creating the rule. */ + tag?: string; +} +export declare type StreamingV2GetRulesResult = DataAndMetaV2; +export interface StreamingV2AddRulesParams { + /** Specifies the operation you want to perform on the rules. */ + add: { + /** + * The tag label. + * This is a free-form text you can use to identify the rules that matched a specific Tweet in the streaming response. + * Tags can be the same across rules. + */ + tag?: string; + /** + * The rule text. + * If you are using a Standard Project at the Basic access level, + * you can use the basic set of operators, can submit up to 25 concurrent rules, and can submit rules up to 512 characters long. + * If you are using an Academic Research Project at the Basic access level, + * you can use all available operators, can submit up to 1,000 concurrent rules, and can submit rules up to 1,024 characters long. + */ + value: string; + }[]; +} +export interface StreamingV2DeleteRulesParams { + /** Specifies the operation you want to perform on the rules. */ + delete: { + /** Array of rule IDs, each one representing a rule already active in your stream. IDs must be submitted as strings. */ + ids: string[]; + }; +} +export declare type StreamingV2UpdateRulesParams = StreamingV2AddRulesParams | StreamingV2DeleteRulesParams; +export interface StreamingV2UpdateRulesQuery { + /** + * Set to true to test a the syntax of your rule without submitting it. + * This is useful if you want to check the syntax of a rule before removing one or more of your existing rules. + */ + dry_run: boolean; +} +export declare type StreamingV2UpdateRulesAddResult = DataAndMetaV2; +export declare type StreamingV2UpdateRulesDeleteResult = MetaV2; +export declare type StreamingV2UpdateRulesResult = StreamingV2UpdateRulesAddResult | StreamingV2UpdateRulesDeleteResult; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/streaming.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/streaming.v2.types.js new file mode 100644 index 0000000..3f5766c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/streaming.v2.types.js @@ -0,0 +1,5 @@ +"use strict"; +// --------------- +// -- Streaming -- +// --------------- +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.d.ts new file mode 100644 index 0000000..1706be8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.d.ts @@ -0,0 +1,205 @@ +import type { UserV2 } from './user.v2.types'; +export interface PlaceV2 { + full_name: string; + id: string; + contained_within?: string[]; + country?: string; + country_code?: string; + geo?: { + type: string; + bbox: number[]; + properties: any; + }; + name?: string; + place_type?: string; +} +export interface PlaybackCountV2 { + playback_0_count: number; + playback_25_count: number; + playback_50_count: number; + playback_75_count: number; + playback_100_count: number; +} +export declare type OrganicMetricV2 = PlaybackCountV2 & { + view_count: number; +}; +export interface MediaVariantsV2 { + bit_rate?: number; + content_type: 'video/mp4' | 'application/x-mpegURL' | string; + url: string; +} +export interface MediaObjectV2 { + media_key: string; + type: 'video' | 'animated_gif' | 'photo' | string; + duration_ms?: number; + height?: number; + width?: number; + url?: string; + preview_image_url?: string; + alt_text?: string; + non_public_metrics?: PlaybackCountV2; + organic_metrics?: OrganicMetricV2; + promoted_metrics?: OrganicMetricV2; + public_metrics?: { + view_count: number; + }; + variants?: MediaVariantsV2[]; +} +export interface PollV2 { + id: string; + options: { + position: number; + label: string; + votes: number; + }[]; + duration_minutes?: number; + end_datetime?: string; + voting_status?: string; +} +export interface ReferencedTweetV2 { + type: 'retweeted' | 'quoted' | 'replied_to'; + id: string; +} +export interface TweetAttachmentV2 { + media_keys?: string[]; + poll_ids?: string[]; +} +export interface TweetGeoV2 { + coordinates: { + type: string; + coordinates: [number, number] | null; + }; + place_id: string; +} +interface TweetContextAnnotationItemV2 { + id: string; + name: string; + description?: string; +} +export declare type TweetContextAnnotationDomainV2 = TweetContextAnnotationItemV2; +export declare type TweetContextAnnotationEntityV2 = TweetContextAnnotationItemV2; +export interface TweetContextAnnotationV2 { + domain: TweetContextAnnotationDomainV2; + entity: TweetContextAnnotationEntityV2; +} +export interface TweetEntityAnnotationsV2 { + start: number; + end: number; + probability: number; + type: string; + normalized_text: string; +} +export interface TweetEntityUrlV2 { + start: number; + end: number; + url: string; + expanded_url: string; + display_url: string; + unwound_url: string; + title?: string; + description?: string; + status?: string; + images?: TweetEntityUrlImageV2[]; +} +export interface TweetEntityUrlImageV2 { + url: string; + width: number; + height: number; +} +export interface TweetEntityHashtagV2 { + start: number; + end: number; + tag: string; +} +export interface TweetEntityMentionV2 { + start: number; + end: number; + username: string; + id: string; +} +export interface TweetEntitiesV2 { + annotations: TweetEntityAnnotationsV2[]; + urls: TweetEntityUrlV2[]; + hashtags: TweetEntityHashtagV2[]; + cashtags: TweetEntityHashtagV2[]; + mentions: TweetEntityMentionV2[]; +} +export interface TweetWithheldInfoV2 { + copyright: boolean; + country_codes: string[]; + scope: 'tweet' | 'user'; +} +export interface TweetPublicMetricsV2 { + retweet_count: number; + reply_count: number; + like_count: number; + quote_count: number; + impression_count: number; +} +export interface TweetNonPublicMetricsV2 { + impression_count: number; + url_link_clicks: number; +} +export interface TweetOrganicMetricsV2 { + impression_count: number; + url_link_clicks: number; + user_profile_clicks: number; + retweet_count: number; + reply_count: number; + like_count: number; +} +export declare type TweetPromotedMetricsV2 = TweetOrganicMetricsV2; +export declare type TTweetReplySettingsV2 = 'mentionedUsers' | 'following' | 'everyone'; +export interface SendTweetV2Params { + direct_message_deep_link?: string; + for_super_followers_only?: 'True' | 'False'; + geo?: { + place_id: string; + }; + media?: { + media_ids?: string[]; + tagged_user_ids?: string[]; + }; + poll?: { + duration_minutes: number; + options: string[]; + }; + quote_tweet_id?: string; + reply?: { + exclude_reply_user_ids?: string[]; + in_reply_to_tweet_id: string; + }; + reply_settings?: TTweetReplySettingsV2 | string; + text?: string; +} +export interface TweetV2 { + id: string; + text: string; + edit_history_tweet_ids: string[]; + created_at?: string; + author_id?: string; + conversation_id?: string; + in_reply_to_user_id?: string; + referenced_tweets?: ReferencedTweetV2[]; + attachments?: TweetAttachmentV2; + geo?: TweetGeoV2; + context_annotations?: TweetContextAnnotationV2[]; + entities?: TweetEntitiesV2; + withheld?: TweetWithheldInfoV2; + public_metrics?: TweetPublicMetricsV2; + non_public_metrics?: TweetNonPublicMetricsV2; + organic_metrics?: TweetOrganicMetricsV2; + promoted_metrics?: TweetPromotedMetricsV2; + possibly_sensitive?: boolean; + lang?: string; + reply_settings?: 'everyone' | 'mentionedUsers' | 'following'; + source?: string; +} +export interface ApiV2Includes { + tweets?: TweetV2[]; + users?: UserV2[]; + places?: PlaceV2[]; + media?: MediaObjectV2[]; + polls?: PollV2[]; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.definition.v2.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.types.d.ts new file mode 100644 index 0000000..f87064b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.types.d.ts @@ -0,0 +1,143 @@ +/// +import type { TweetV2, ApiV2Includes } from './tweet.definition.v2'; +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataAndMetaV2, DataMetaAndIncludeV2, DataV2, MetaV2 } from './shared.v2.types'; +import { UserV2 } from './user.v2.types'; +import { PaginableCountMetaV2 } from './shared.v2.types'; +export interface TweetV2TimelineParams extends Partial { + /** ISO date string */ + end_time?: string; + /** ISO date string */ + start_time?: string; + max_results?: number; + since_id?: string; + until_id?: string; + next_token?: string; +} +export interface Tweetv2SearchParams extends TweetV2TimelineParams { + previous_token?: string; + query: string; + sort_order?: 'recency' | 'relevancy'; +} +export interface TweetV2PaginableTimelineParams extends TweetV2TimelineParams { + pagination_token?: string; +} +export interface TweetV2PaginableListParams extends Partial { + pagination_token?: string; + max_results?: number; +} +export interface TweetV2UserTimelineParams extends TweetV2PaginableTimelineParams { + exclude?: TypeOrArrayOf<'retweets' | 'replies'>; +} +export interface TweetV2HomeTimelineParams extends TweetV2UserTimelineParams { +} +export declare type TTweetv2Expansion = 'attachments.poll_ids' | 'attachments.media_keys' | 'author_id' | 'referenced_tweets.id' | 'in_reply_to_user_id' | 'edit_history_tweet_ids' | 'geo.place_id' | 'entities.mentions.username' | 'referenced_tweets.id.author_id'; +export declare type TTweetv2MediaField = 'duration_ms' | 'height' | 'media_key' | 'preview_image_url' | 'type' | 'url' | 'width' | 'public_metrics' | 'non_public_metrics' | 'organic_metrics' | 'alt_text' | 'variants'; +export declare type TTweetv2PlaceField = 'contained_within' | 'country' | 'country_code' | 'full_name' | 'geo' | 'id' | 'name' | 'place_type'; +export declare type TTweetv2PollField = 'duration_minutes' | 'end_datetime' | 'id' | 'options' | 'voting_status'; +export declare type TTweetv2TweetField = 'attachments' | 'author_id' | 'context_annotations' | 'conversation_id' | 'created_at' | 'entities' | 'geo' | 'id' | 'in_reply_to_user_id' | 'lang' | 'public_metrics' | 'non_public_metrics' | 'promoted_metrics' | 'organic_metrics' | 'edit_controls' | 'possibly_sensitive' | 'referenced_tweets' | 'reply_settings' | 'source' | 'text' | 'withheld'; +export declare type TTweetv2UserField = 'created_at' | 'description' | 'entities' | 'id' | 'location' | 'name' | 'pinned_tweet_id' | 'profile_image_url' | 'protected' | 'public_metrics' | 'url' | 'username' | 'verified' | 'verified_type' | 'withheld'; +export interface Tweetv2FieldsParams { + expansions: TypeOrArrayOf | string; + 'media.fields': TypeOrArrayOf | string; + 'place.fields': TypeOrArrayOf | string; + 'poll.fields': TypeOrArrayOf | string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface TweetSearchV2StreamParams extends Tweetv2FieldsParams { + backfill_minutes: number; +} +export interface TweetV2CountParams { + query: string; + end_time?: string; + start_time?: string; + until_id?: string; + since_id?: string; + granularity?: 'day' | 'hour' | 'minute'; +} +export interface TweetV2CountAllParams extends TweetV2CountParams { + next_token: string; +} +export declare type TweetV2CountResult = DataAndMetaV2<{ + start: string; + end: string; + tweet_count: number; +}[], { + total_tweet_count: number; +}>; +export declare type TweetV2CountAllResult = TweetV2CountResult & MetaV2<{ + next_token: string; +}>; +export declare type Tweetv2TimelineResult = DataMetaAndIncludeV2; +export declare type Tweetv2ListResult = DataMetaAndIncludeV2; +export declare type Tweetv2SearchResult = Tweetv2TimelineResult; +export declare type TweetV2PaginableTimelineResult = Tweetv2TimelineResult & MetaV2<{ + previous_token?: string; +}>; +export declare type TweetV2UserTimelineResult = TweetV2PaginableTimelineResult; +export declare type TweetV2HomeTimelineResult = TweetV2PaginableTimelineResult; +export declare type TweetV2LookupResult = DataAndIncludeV2; +export declare type TweetV2SingleResult = DataAndIncludeV2; +export declare type TweetV2SingleStreamResult = TweetV2SingleResult & { + matching_rules: { + id: string | number; + tag: string; + }[]; +}; +export declare type TweetV2PostTweetResult = DataV2<{ + id: string; + text: string; +}>; +export declare type TweetV2HideReplyResult = DataV2<{ + hidden: boolean; +}>; +export declare type TweetV2LikeResult = DataV2<{ + liked: boolean; +}>; +export declare type TweetV2LikedByResult = DataMetaAndIncludeV2; +export declare type TweetV2RetweetResult = DataV2<{ + retweeted: boolean; +}>; +export declare type TweetV2RetweetedByResult = TweetV2LikedByResult; +export declare type TweetV2BookmarkResult = DataV2<{ + bookmarked: boolean; +}>; +export declare type TweetV2DeleteTweetResult = DataV2<{ + deleted: boolean; +}>; +export interface BatchComplianceJobV2 { + resumable: false; + type: 'tweets' | 'users'; + download_expires_at: string; + created_at: string; + upload_url: string; + download_url: string; + id: string; + status: 'created' | 'complete' | 'in_progress' | 'expired' | 'failed'; + upload_expires_at: string; + error?: string; +} +export interface BatchComplianceSearchV2Params { + type: 'tweets' | 'users'; + status?: 'created' | 'complete' | 'in_progress' | 'expired' | 'failed'; +} +export interface BatchComplianceV2Params { + type: 'tweets' | 'users'; + name?: string; + ids: string[] | Buffer; +} +export interface BatchComplianceV2JobResult { + id: string; + action: 'delete'; + created_at: string; + redacted_at?: string; + reason: 'deleted' | 'suspended' | 'protected' | 'scrub_geo' | 'deactivated'; +} +export declare type BatchComplianceListV2Result = DataV2; +export declare type BatchComplianceV2Result = DataV2; diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/tweet.v2.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/v2/user.v2.types.d.ts b/node_modules/twitter-api-v2/dist/cjs/types/v2/user.v2.types.d.ts new file mode 100644 index 0000000..115b3af --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/user.v2.types.d.ts @@ -0,0 +1,96 @@ +import type { CashtagEntity, HashtagEntity, MentionEntity, UrlEntity } from '../entities.types'; +import type { ApiV2Includes } from './tweet.definition.v2'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2, DataV2 } from './shared.v2.types'; +import type { TTweetv2MediaField, TTweetv2PlaceField, TTweetv2PollField, TTweetv2TweetField, TTweetv2UserField } from './tweet.v2.types'; +import type { TypeOrArrayOf } from '../shared.types'; +import { PaginableCountMetaV2 } from './shared.v2.types'; +export declare type TUserV2Expansion = 'pinned_tweet_id'; +export interface UsersV2Params { + expansions: TypeOrArrayOf; + 'media.fields': TypeOrArrayOf | string; + 'place.fields': TypeOrArrayOf | string; + 'poll.fields': TypeOrArrayOf | string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface UserV2TimelineParams { + expansions?: TypeOrArrayOf; + 'media.fields'?: TypeOrArrayOf | string; + 'place.fields'?: TypeOrArrayOf | string; + 'poll.fields'?: TypeOrArrayOf | string; + 'tweet.fields'?: TypeOrArrayOf | string; + 'user.fields'?: TypeOrArrayOf | string; + max_results?: number; + pagination_token?: string; +} +export interface TweetRetweetedOrLikedByV2Params extends Partial { + asPaginator?: boolean; +} +export interface TweetRetweetedOrLikedByV2ParamsWithoutPaginator extends TweetRetweetedOrLikedByV2Params { + asPaginator?: false; +} +export interface TweetRetweetedOrLikedByV2ParamsWithPaginator extends TweetRetweetedOrLikedByV2Params { + asPaginator: true; +} +export interface FollowersV2Params extends UserV2TimelineParams { + asPaginator?: boolean; +} +export interface FollowersV2ParamsWithoutPaginator extends FollowersV2Params { + asPaginator?: false; +} +export interface FollowersV2ParamsWithPaginator extends FollowersV2Params { + asPaginator: true; +} +export declare type UserV2Result = DataAndIncludeV2; +export declare type UsersV2Result = DataAndIncludeV2; +export declare type UserV2FollowResult = DataV2<{ + following: boolean; + pending_follow: boolean; +}>; +export declare type UserV2UnfollowResult = DataV2<{ + following: boolean; +}>; +export declare type UserV2BlockResult = DataV2<{ + blocking: boolean; +}>; +export declare type UserV2MuteResult = DataV2<{ + muting: boolean; +}>; +export declare type UserV2TimelineResult = DataMetaAndIncludeV2; +/** @deprecated Use {UserV2TimelineResult} instead. */ +export declare type FollowersV2Result = UserV2TimelineResult; +export interface UserV2 { + id: string; + name: string; + username: string; + created_at?: string; + protected?: boolean; + withheld?: { + country_codes?: string[]; + scope?: 'user'; + }; + location?: string; + url?: string; + description?: string; + verified?: boolean; + verified_type?: "none" | "blue" | "business" | "government"; + entities?: { + url?: { + urls: UrlEntity[]; + }; + description: { + urls?: UrlEntity[]; + hashtags?: HashtagEntity[]; + cashtags?: CashtagEntity[]; + mentions?: MentionEntity[]; + }; + }; + profile_image_url?: string; + public_metrics?: { + followers_count?: number; + following_count?: number; + tweet_count?: number; + listed_count?: number; + }; + pinned_tweet_id?: string; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/types/v2/user.v2.types.js b/node_modules/twitter-api-v2/dist/cjs/types/v2/user.v2.types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/types/v2/user.v2.types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.d.ts new file mode 100644 index 0000000..38acc60 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.d.ts @@ -0,0 +1,109 @@ +/// +import { DmEventsV1Paginator, WelcomeDmV1Paginator } from '../paginators/dm.paginator.v1'; +import { SendDMV1Params, DirectMessageCreateV1Result, ReceivedDMEventV1, GetDmListV1Args, MessageCreateDataV1, WelcomeDirectMessageCreateV1Result, WelcomeDmRuleV1Result, WelcomeDmRuleListV1Result, DirectMessageCreateV1 } from '../types'; +import TwitterApiv1ReadWrite from './client.v1.write'; +/** + * Twitter v1.1 API client with read/write/DMs rights. + */ +export declare class TwitterApiv1 extends TwitterApiv1ReadWrite { + protected _prefix: string; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv1ReadWrite; + /** + * Publishes a new message_create event resulting in a Direct Message sent to a specified user from the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event + */ + sendDm({ recipient_id, custom_profile_id, ...params }: SendDMV1Params): Promise; + /** + * Returns a single Direct Message event by the given id. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/get-event + */ + getDmEvent(id: string): Promise; + /** + * Deletes the direct message specified in the required ID parameter. + * The authenticating user must be the recipient of the specified direct message. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/delete-message-event + */ + deleteDm(id: string): Promise; + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + listDmEvents(args?: Partial): Promise; + /** + * Creates a new Welcome Message that will be stored and sent in the future from the authenticating user in defined circumstances. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message + */ + newWelcomeDm(name: string, data: MessageCreateDataV1): Promise; + /** + * Returns a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message + */ + getWelcomeDm(id: string): Promise; + /** + * Deletes a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message + */ + deleteWelcomeDm(id: string): Promise; + /** + * Updates a Welcome Message by the given ID. + * Updates to the welcome_message object are atomic. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/update-welcome-message + */ + updateWelcomeDm(id: string, data: MessageCreateDataV1): Promise; + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + listWelcomeDms(args?: Partial): Promise; + /** + * Creates a new Welcome Message Rule that determines which Welcome Message will be shown in a given conversation. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message-rule + */ + newWelcomeDmRule(welcomeMessageId: string): Promise; + /** + * Returns a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message-rule + */ + getWelcomeDmRule(id: string): Promise; + /** + * Deletes a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule + */ + deleteWelcomeDmRule(id: string): Promise; + /** + * Retrieves all welcome DM rules for this account. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/list-welcome-message-rules + */ + listWelcomeDmRules(args?: Partial): Promise; + /** + * Set the current showed welcome message for logged account ; wrapper for Welcome DM rules. + * Test if a rule already exists, delete if any, then create a rule for current message ID. + * + * If you don't have already a welcome message, create it with `.newWelcomeMessage`. + */ + setWelcomeDm(welcomeMessageId: string, deleteAssociatedWelcomeDmWhenDeletingRule?: boolean): Promise; + /** + * Marks a message as read in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-read-receipt + */ + markDmAsRead(lastEventId: string, recipientId: string): Promise; + /** + * Displays a visual typing indicator in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-typing-indicator + */ + indicateDmTyping(recipientId: string): Promise; + /** + * Get a single image attached to a direct message. TwitterApi client must be logged with OAuth 1.0a. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/message-attachments/guides/retrieving-media + */ + downloadDmImage(urlOrDm: string | DirectMessageCreateV1): Promise; +} +export default TwitterApiv1; diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.js b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.js new file mode 100644 index 0000000..8e40d42 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.js @@ -0,0 +1,232 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TwitterApiv1 = void 0; +const globals_1 = require("../globals"); +const dm_paginator_v1_1 = require("../paginators/dm.paginator.v1"); +const types_1 = require("../types"); +const client_v1_write_1 = __importDefault(require("./client.v1.write")); +/** + * Twitter v1.1 API client with read/write/DMs rights. + */ +class TwitterApiv1 extends client_v1_write_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V1_1_PREFIX; + } + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } + /* Direct messages */ + // Part: Sending and receiving events + /** + * Publishes a new message_create event resulting in a Direct Message sent to a specified user from the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event + */ + sendDm({ recipient_id, custom_profile_id, ...params }) { + const args = { + event: { + type: types_1.EDirectMessageEventTypeV1.Create, + [types_1.EDirectMessageEventTypeV1.Create]: { + target: { recipient_id }, + message_data: params, + }, + }, + }; + if (custom_profile_id) { + args.event[types_1.EDirectMessageEventTypeV1.Create].custom_profile_id = custom_profile_id; + } + return this.post('direct_messages/events/new.json', args, { + forceBodyMode: 'json', + }); + } + /** + * Returns a single Direct Message event by the given id. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/get-event + */ + getDmEvent(id) { + return this.get('direct_messages/events/show.json', { id }); + } + /** + * Deletes the direct message specified in the required ID parameter. + * The authenticating user must be the recipient of the specified direct message. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/delete-message-event + */ + deleteDm(id) { + return this.delete('direct_messages/events/destroy.json', { id }); + } + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + async listDmEvents(args = {}) { + const queryParams = { ...args }; + const initialRq = await this.get('direct_messages/events/list.json', queryParams, { fullResponse: true }); + return new dm_paginator_v1_1.DmEventsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + // Part: Welcome messages (events) + /** + * Creates a new Welcome Message that will be stored and sent in the future from the authenticating user in defined circumstances. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message + */ + newWelcomeDm(name, data) { + const args = { + [types_1.EDirectMessageEventTypeV1.WelcomeCreate]: { + name, + message_data: data, + }, + }; + return this.post('direct_messages/welcome_messages/new.json', args, { + forceBodyMode: 'json', + }); + } + /** + * Returns a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message + */ + getWelcomeDm(id) { + return this.get('direct_messages/welcome_messages/show.json', { id }); + } + /** + * Deletes a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message + */ + deleteWelcomeDm(id) { + return this.delete('direct_messages/welcome_messages/destroy.json', { id }); + } + /** + * Updates a Welcome Message by the given ID. + * Updates to the welcome_message object are atomic. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/update-welcome-message + */ + updateWelcomeDm(id, data) { + const args = { message_data: data }; + return this.put('direct_messages/welcome_messages/update.json', args, { + forceBodyMode: 'json', + query: { id }, + }); + } + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + async listWelcomeDms(args = {}) { + const queryParams = { ...args }; + const initialRq = await this.get('direct_messages/welcome_messages/list.json', queryParams, { fullResponse: true }); + return new dm_paginator_v1_1.WelcomeDmV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + // Part: Welcome message (rules) + /** + * Creates a new Welcome Message Rule that determines which Welcome Message will be shown in a given conversation. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message-rule + */ + newWelcomeDmRule(welcomeMessageId) { + return this.post('direct_messages/welcome_messages/rules/new.json', { + welcome_message_rule: { welcome_message_id: welcomeMessageId }, + }, { + forceBodyMode: 'json', + }); + } + /** + * Returns a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message-rule + */ + getWelcomeDmRule(id) { + return this.get('direct_messages/welcome_messages/rules/show.json', { id }); + } + /** + * Deletes a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule + */ + deleteWelcomeDmRule(id) { + return this.delete('direct_messages/welcome_messages/rules/destroy.json', { id }); + } + /** + * Retrieves all welcome DM rules for this account. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/list-welcome-message-rules + */ + async listWelcomeDmRules(args = {}) { + const queryParams = { ...args }; + return this.get('direct_messages/welcome_messages/rules/list.json', queryParams); + } + /** + * Set the current showed welcome message for logged account ; wrapper for Welcome DM rules. + * Test if a rule already exists, delete if any, then create a rule for current message ID. + * + * If you don't have already a welcome message, create it with `.newWelcomeMessage`. + */ + async setWelcomeDm(welcomeMessageId, deleteAssociatedWelcomeDmWhenDeletingRule = true) { + var _a; + const existingRules = await this.listWelcomeDmRules(); + if ((_a = existingRules.welcome_message_rules) === null || _a === void 0 ? void 0 : _a.length) { + for (const rule of existingRules.welcome_message_rules) { + await this.deleteWelcomeDmRule(rule.id); + if (deleteAssociatedWelcomeDmWhenDeletingRule) { + await this.deleteWelcomeDm(rule.welcome_message_id); + } + } + } + return this.newWelcomeDmRule(welcomeMessageId); + } + // Part: Read indicator + /** + * Marks a message as read in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-read-receipt + */ + markDmAsRead(lastEventId, recipientId) { + return this.post('direct_messages/mark_read.json', { + last_read_event_id: lastEventId, + recipient_id: recipientId, + }, { forceBodyMode: 'url' }); + } + /** + * Displays a visual typing indicator in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-typing-indicator + */ + indicateDmTyping(recipientId) { + return this.post('direct_messages/indicate_typing.json', { + recipient_id: recipientId, + }, { forceBodyMode: 'url' }); + } + // Part: Images + /** + * Get a single image attached to a direct message. TwitterApi client must be logged with OAuth 1.0a. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/message-attachments/guides/retrieving-media + */ + async downloadDmImage(urlOrDm) { + if (typeof urlOrDm !== 'string') { + const attachment = urlOrDm[types_1.EDirectMessageEventTypeV1.Create].message_data.attachment; + if (!attachment) { + throw new Error('The given direct message doesn\'t contain any attachment'); + } + urlOrDm = attachment.media.media_url_https; + } + const data = await this.get(urlOrDm, undefined, { forceParseMode: 'buffer', prefix: '' }); + if (!data.length) { + throw new Error('Image not found. Make sure you are logged with credentials able to access direct messages, and check the URL.'); + } + return data; + } +} +exports.TwitterApiv1 = TwitterApiv1; +exports.default = TwitterApiv1; diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.d.ts b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.d.ts new file mode 100644 index 0000000..b4f69c5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.d.ts @@ -0,0 +1,297 @@ +import TwitterApiSubClient from '../client.subclient'; +import { FilterStreamV1Params, SampleStreamV1Params, UserV1, VerifyCredentialsV1Params, AppRateLimitV1Result, TAppRateLimitResourceV1, HelpLanguageV1Result, ReverseGeoCodeV1Params, ReverseGeoCodeV1Result, PlaceV1, SearchGeoV1Params, SearchGeoV1Result, TrendMatchV1, TrendsPlaceV1Params, TrendLocationV1, TweetV1TimelineParams, TweetV1UserTimelineParams, TweetV1, MediaStatusV1Result, OembedTweetV1Params, OembedTweetV1Result, MuteUserListV1Params, MuteUserIdsV1Params, UserFollowerIdsV1Params, UserFollowingsIdsV1Params, UserFriendListV1Params, UserFollowerListV1Params, UserSearchV1Params, AccountSettingsV1, ProfileBannerSizeV1, ProfileBannerSizeV1Params, FriendshipLookupV1Params, FriendshipLookupV1, FriendshipShowV1Params, FriendshipV1, FriendshipsIncomingV1Params, UserShowV1Params, UserLookupV1Params, TweetShowV1Params, TweetLookupNoMapV1Params, TweetLookupMapV1Params, TweetLookupMapV1Result, ListListsV1Params, ListV1, ListMembersV1Params, ListMemberShowV1Params, ListMembershipsV1Params, ListOwnershipsV1Params, GetListV1Params, ListStatusesV1Params, ListSubscriptionsV1Params } from '../types'; +import { HomeTimelineV1Paginator, ListTimelineV1Paginator, MentionTimelineV1Paginator, UserFavoritesV1Paginator, UserTimelineV1Paginator } from '../paginators/tweet.paginator.v1'; +import { MuteUserIdsV1Paginator, MuteUserListV1Paginator } from '../paginators/mutes.paginator.v1'; +import { UserFollowerIdsV1Paginator, UserFollowerListV1Paginator } from '../paginators/followers.paginator.v1'; +import { UserFollowersIdsV1Paginator, UserFriendListV1Paginator } from '../paginators/friends.paginator.v1'; +import { FriendshipsIncomingV1Paginator, FriendshipsOutgoingV1Paginator, UserSearchV1Paginator } from '../paginators/user.paginator.v1'; +import { ListMembershipsV1Paginator, ListMembersV1Paginator, ListOwnershipsV1Paginator, ListSubscribersV1Paginator, ListSubscriptionsV1Paginator } from '../paginators/list.paginator.v1'; +import TweetStream from '../stream/TweetStream'; +import { PromiseOrType } from '../types/shared.types'; +/** + * Base Twitter v1 client with only read right. + */ +export default class TwitterApiv1ReadOnly extends TwitterApiSubClient { + protected _prefix: string; + /** + * Returns a single Tweet, specified by the id parameter. The Tweet's author will also be embedded within the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id + */ + singleTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns fully-hydrated Tweet objects for up to 100 Tweets per request. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-lookup + */ + tweets(ids: string | string[], options?: TweetLookupNoMapV1Params): Promise; + tweets(ids: string | string[], options: TweetLookupMapV1Params): Promise; + /** + * Returns a single Tweet, specified by either a Tweet web URL or the Tweet ID, in an oEmbed-compatible format. + * The returned HTML snippet will be automatically recognized as an Embedded Tweet when Twitter's widget JavaScript is included on the page. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-oembed + */ + oembedTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets and Retweets posted by the authenticating user and the users they follow. + * The home timeline is central to how most users interact with the Twitter service. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-home_timeline + */ + homeTimeline(options?: Partial): Promise; + /** + * Returns the 20 most recent mentions (Tweets containing a users's @screen_name) for the authenticating user. + * The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-mentions_timeline + */ + mentionTimeline(options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the user_id parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + userTimeline(userId: string, options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the screen_name parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + userTimelineByUsername(username: string, options?: Partial): Promise; + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + favoriteTimeline(userId: string, options?: Partial): Promise; + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + favoriteTimelineByUsername(username: string, options?: Partial): Promise; + /** + * Returns a variety of information about the user specified by the required user_id or screen_name parameter. + * The author's most recent Tweet will be returned inline when possible. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-show + */ + user(user: UserShowV1Params): Promise; + /** + * Returns fully-hydrated user objects for up to 100 users per request, + * as specified by comma-separated values passed to the user_id and/or screen_name parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup + */ + users(query: UserLookupV1Params): Promise; + /** + * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; + * returns a 401 status code and an error message if not. + * Use this method to test if supplied user credentials are valid. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials + */ + verifyCredentials(options?: Partial): Promise; + /** + * Returns an array of user objects the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list + */ + listMutedUsers(options?: Partial): Promise; + /** + * Returns an array of numeric user ids the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids + */ + listMutedUserIds(options?: Partial): Promise; + /** + * Returns an array of user objects of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-list + */ + userFriendList(options?: Partial): Promise; + /** + * Returns an array of user objects of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-list + */ + userFollowerList(options?: Partial): Promise; + /** + * Returns an array of numeric user ids of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids + */ + userFollowerIds(options?: Partial): Promise; + /** + * Returns an array of numeric user ids of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids + */ + userFollowingIds(options?: Partial): Promise; + /** + * Provides a simple, relevance-based search interface to public user accounts on Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search + */ + searchUsers(query: string, options?: Partial): Promise; + /** + * Returns detailed information about the relationship between two arbitrary users. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show + */ + friendship(sources: FriendshipShowV1Params): Promise; + /** + * Returns the relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup + */ + friendships(friendships: FriendshipLookupV1Params): Promise; + /** + * Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids + */ + friendshipsNoRetweets(): Promise; + /** + * Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming + */ + friendshipsIncoming(options?: Partial): Promise; + /** + * Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing + */ + friendshipsOutgoing(options?: Partial): Promise; + /** + * Get current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + accountSettings(): Promise; + /** + * Returns a map of the available size variations of the specified user's profile banner. + * If the user has not uploaded a profile banner, a HTTP 404 will be served instead. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-users-profile_banner + */ + userProfileBannerSizes(params: ProfileBannerSizeV1Params): Promise; + /** + * Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-show + */ + list(options: GetListV1Params): Promise; + /** + * Returns all lists the authenticating or specified user subscribes to, including their own. + * If no user is given, the authenticating user is used. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-list + */ + lists(options?: ListListsV1Params): Promise; + /** + * Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members + */ + listMembers(options?: Partial): Promise; + /** + * Check if the specified user is a member of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show + */ + listGetMember(options: ListMemberShowV1Params): Promise; + /** + * Returns the lists the specified user has been added to. + * If user_id or screen_name are not provided, the memberships for the authenticating user are returned. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships + */ + listMemberships(options?: Partial): Promise; + /** + * Returns the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships + */ + listOwnerships(options?: Partial): Promise; + /** + * Returns a timeline of tweets authored by members of the specified list. Retweets are included by default. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses + */ + listStatuses(options: Partial): Promise; + /** + * Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers + */ + listSubscribers(options?: Partial): Promise; + /** + * Check if the specified user is a subscriber of the specified list. Returns the user if they are a subscriber. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show + */ + listGetSubscriber(options: ListMemberShowV1Params): Promise; + /** + * Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. + * Does not include the user's own lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions + */ + listSubscriptions(options?: Partial): Promise; + /** + * The STATUS command (this method) is used to periodically poll for updates of media processing operation. + * After the STATUS command response returns succeeded, you can move on to the next step which is usually create Tweet with media_id. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/get-media-upload-status + */ + mediaInfo(mediaId: string): Promise; + /** + * Returns public statuses that match one or more filter predicates. + * Multiple parameters may be specified which allows most clients to use a single connection to the Streaming API. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/api-reference/post-statuses-filter + */ + filterStream(params?: Partial & { + autoConnect?: true; + }): Promise>; + filterStream(params: Partial & { + autoConnect: false; + }): TweetStream; + filterStream(params?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Returns a small random sample of all public statuses. + * The Tweets returned by the default access level are the same, so if two different clients connect to this endpoint, they will see the same Tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/sample-realtime/api-reference/get-statuses-sample + */ + sampleStream(params?: Partial & { + autoConnect?: true; + }): Promise>; + sampleStream(params: Partial & { + autoConnect: false; + }): TweetStream; + sampleStream(params?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Create a client that is prefixed with `https//stream.twitter.com` instead of classic API URL. + */ + get stream(): this; + /** + * Returns the top 50 trending topics for a specific id, if trending information is available for it. + * Note: The id parameter for this endpoint is the "where on earth identifier" or WOEID, which is a legacy identifier created by Yahoo and has been deprecated. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/trends-for-location/api-reference/get-trends-place + */ + trendsByPlace(woeId: string | number, options?: Partial): Promise; + /** + * Returns the locations that Twitter has trending topic information for. + * The response is an array of "locations" that encode the location's WOEID + * and some other human-readable information such as a canonical name and country the location belongs in. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-available + */ + trendsAvailable(): Promise; + /** + * Returns the locations that Twitter has trending topic information for, closest to a specified location. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-closest + */ + trendsClosest(lat: number, long: number): Promise; + /** + * Returns all the information about a known place. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/place-information/api-reference/get-geo-id-place_id + */ + geoPlace(placeId: string): Promise; + /** + * Search for places that can be attached to a Tweet via POST statuses/update. + * This request will return a list of all the valid places that can be used as the place_id when updating a status. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-search + */ + geoSearch(options: Partial): Promise; + /** + * Given a latitude and a longitude, searches for up to 20 places that can be used as a place_id when updating a status. + * This request is an informative call and will deliver generalized results about geography. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-reverse_geocode + */ + geoReverseGeoCode(options: ReverseGeoCodeV1Params): Promise; + /** + * Returns the current rate limits for methods belonging to the specified resource families. + * Each API resource belongs to a "resource family" which is indicated in its method documentation. + * The method's resource family can be determined from the first component of the path after the resource version. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status + */ + rateLimitStatuses(...resources: TAppRateLimitResourceV1[]): Promise; + /** + * Returns the list of languages supported by Twitter along with the language code supported by Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/supported-languages/api-reference/get-help-languages + */ + supportedLanguages(): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.js b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.js new file mode 100644 index 0000000..27a476d --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.read.js @@ -0,0 +1,618 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const client_subclient_1 = __importDefault(require("../client.subclient")); +const globals_1 = require("../globals"); +const helpers_1 = require("../helpers"); +const client_v1_1 = __importDefault(require("../v1/client.v1")); +const tweet_paginator_v1_1 = require("../paginators/tweet.paginator.v1"); +const mutes_paginator_v1_1 = require("../paginators/mutes.paginator.v1"); +const followers_paginator_v1_1 = require("../paginators/followers.paginator.v1"); +const friends_paginator_v1_1 = require("../paginators/friends.paginator.v1"); +const user_paginator_v1_1 = require("../paginators/user.paginator.v1"); +const list_paginator_v1_1 = require("../paginators/list.paginator.v1"); +/** + * Base Twitter v1 client with only read right. + */ +class TwitterApiv1ReadOnly extends client_subclient_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V1_1_PREFIX; + } + /* Tweets */ + /** + * Returns a single Tweet, specified by the id parameter. The Tweet's author will also be embedded within the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id + */ + singleTweet(tweetId, options = {}) { + return this.get('statuses/show.json', { tweet_mode: 'extended', id: tweetId, ...options }); + } + tweets(ids, options = {}) { + return this.post('statuses/lookup.json', { tweet_mode: 'extended', id: ids, ...options }); + } + /** + * Returns a single Tweet, specified by either a Tweet web URL or the Tweet ID, in an oEmbed-compatible format. + * The returned HTML snippet will be automatically recognized as an Embedded Tweet when Twitter's widget JavaScript is included on the page. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-oembed + */ + oembedTweet(tweetId, options = {}) { + return this.get('oembed', { + url: `https://twitter.com/i/statuses/${tweetId}`, + ...options, + }, { prefix: 'https://publish.twitter.com/' }); + } + /* Tweets timelines */ + /** + * Returns a collection of the most recent Tweets and Retweets posted by the authenticating user and the users they follow. + * The home timeline is central to how most users interact with the Twitter service. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-home_timeline + */ + async homeTimeline(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('statuses/home_timeline.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.HomeTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the 20 most recent mentions (Tweets containing a users's @screen_name) for the authenticating user. + * The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-mentions_timeline + */ + async mentionTimeline(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('statuses/mentions_timeline.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.MentionTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the user_id parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + async userTimeline(userId, options = {}) { + const queryParams = { + tweet_mode: 'extended', + user_id: userId, + ...options, + }; + const initialRq = await this.get('statuses/user_timeline.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.UserTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the screen_name parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + async userTimelineByUsername(username, options = {}) { + const queryParams = { + tweet_mode: 'extended', + screen_name: username, + ...options, + }; + const initialRq = await this.get('statuses/user_timeline.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.UserTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + async favoriteTimeline(userId, options = {}) { + const queryParams = { + tweet_mode: 'extended', + user_id: userId, + ...options, + }; + const initialRq = await this.get('favorites/list.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.UserFavoritesV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + async favoriteTimelineByUsername(username, options = {}) { + const queryParams = { + tweet_mode: 'extended', + screen_name: username, + ...options, + }; + const initialRq = await this.get('favorites/list.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.UserFavoritesV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Users */ + /** + * Returns a variety of information about the user specified by the required user_id or screen_name parameter. + * The author's most recent Tweet will be returned inline when possible. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-show + */ + user(user) { + return this.get('users/show.json', { tweet_mode: 'extended', ...user }); + } + /** + * Returns fully-hydrated user objects for up to 100 users per request, + * as specified by comma-separated values passed to the user_id and/or screen_name parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup + */ + users(query) { + return this.get('users/lookup.json', { tweet_mode: 'extended', ...query }); + } + /** + * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; + * returns a 401 status code and an error message if not. + * Use this method to test if supplied user credentials are valid. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials + */ + verifyCredentials(options = {}) { + return this.get('account/verify_credentials.json', options); + } + /** + * Returns an array of user objects the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list + */ + async listMutedUsers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('mutes/users/list.json', queryParams, { fullResponse: true }); + return new mutes_paginator_v1_1.MuteUserListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids + */ + async listMutedUserIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('mutes/users/ids.json', queryParams, { fullResponse: true }); + return new mutes_paginator_v1_1.MuteUserIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of user objects of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-list + */ + async userFriendList(options = {}) { + const queryParams = { + ...options, + }; + const initialRq = await this.get('friends/list.json', queryParams, { fullResponse: true }); + return new friends_paginator_v1_1.UserFriendListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of user objects of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-list + */ + async userFollowerList(options = {}) { + const queryParams = { + ...options, + }; + const initialRq = await this.get('followers/list.json', queryParams, { fullResponse: true }); + return new followers_paginator_v1_1.UserFollowerListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids + */ + async userFollowerIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('followers/ids.json', queryParams, { fullResponse: true }); + return new followers_paginator_v1_1.UserFollowerIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids + */ + async userFollowingIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friends/ids.json', queryParams, { fullResponse: true }); + return new friends_paginator_v1_1.UserFollowersIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Provides a simple, relevance-based search interface to public user accounts on Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search + */ + async searchUsers(query, options = {}) { + const queryParams = { + q: query, + tweet_mode: 'extended', + page: 1, + ...options, + }; + const initialRq = await this.get('users/search.json', queryParams, { fullResponse: true }); + return new user_paginator_v1_1.UserSearchV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Friendship API */ + /** + * Returns detailed information about the relationship between two arbitrary users. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show + */ + friendship(sources) { + return this.get('friendships/show.json', sources); + } + /** + * Returns the relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup + */ + friendships(friendships) { + return this.get('friendships/lookup.json', friendships); + } + /** + * Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids + */ + friendshipsNoRetweets() { + return this.get('friendships/no_retweets/ids.json', { stringify_ids: true }); + } + /** + * Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming + */ + async friendshipsIncoming(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friendships/incoming.json', queryParams, { fullResponse: true }); + return new user_paginator_v1_1.FriendshipsIncomingV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing + */ + async friendshipsOutgoing(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friendships/outgoing.json', queryParams, { fullResponse: true }); + return new user_paginator_v1_1.FriendshipsOutgoingV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Account/user API */ + /** + * Get current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + accountSettings() { + return this.get('account/settings.json'); + } + /** + * Returns a map of the available size variations of the specified user's profile banner. + * If the user has not uploaded a profile banner, a HTTP 404 will be served instead. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-users-profile_banner + */ + userProfileBannerSizes(params) { + return this.get('users/profile_banner.json', params); + } + /* Lists */ + /** + * Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-show + */ + list(options) { + return this.get('lists/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns all lists the authenticating or specified user subscribes to, including their own. + * If no user is given, the authenticating user is used. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-list + */ + lists(options = {}) { + return this.get('lists/list.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members + */ + async listMembers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/members.json', queryParams, { fullResponse: true }); + return new list_paginator_v1_1.ListMembersV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Check if the specified user is a member of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show + */ + listGetMember(options) { + return this.get('lists/members/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns the lists the specified user has been added to. + * If user_id or screen_name are not provided, the memberships for the authenticating user are returned. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships + */ + async listMemberships(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/memberships.json', queryParams, { fullResponse: true }); + return new list_paginator_v1_1.ListMembershipsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships + */ + async listOwnerships(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/ownerships.json', queryParams, { fullResponse: true }); + return new list_paginator_v1_1.ListOwnershipsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a timeline of tweets authored by members of the specified list. Retweets are included by default. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses + */ + async listStatuses(options) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/statuses.json', queryParams, { fullResponse: true }); + return new tweet_paginator_v1_1.ListTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers + */ + async listSubscribers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/subscribers.json', queryParams, { fullResponse: true }); + return new list_paginator_v1_1.ListSubscribersV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Check if the specified user is a subscriber of the specified list. Returns the user if they are a subscriber. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show + */ + listGetSubscriber(options) { + return this.get('lists/subscribers/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. + * Does not include the user's own lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions + */ + async listSubscriptions(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/subscriptions.json', queryParams, { fullResponse: true }); + return new list_paginator_v1_1.ListSubscriptionsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Media upload API */ + /** + * The STATUS command (this method) is used to periodically poll for updates of media processing operation. + * After the STATUS command response returns succeeded, you can move on to the next step which is usually create Tweet with media_id. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/get-media-upload-status + */ + mediaInfo(mediaId) { + return this.get('media/upload.json', { + command: 'STATUS', + media_id: mediaId, + }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX }); + } + filterStream({ autoConnect, ...params } = {}) { + const parameters = {}; + for (const [key, value] of Object.entries(params)) { + if (key === 'follow' || key === 'track') { + parameters[key] = value.toString(); + } + else if (key === 'locations') { + const locations = value; + parameters.locations = (0, helpers_1.arrayWrap)(locations).map(loc => `${loc.lng},${loc.lat}`).join(','); + } + else { + parameters[key] = value; + } + } + const streamClient = this.stream; + return streamClient.postStream('statuses/filter.json', parameters, { autoConnect }); + } + sampleStream({ autoConnect, ...params } = {}) { + const streamClient = this.stream; + return streamClient.getStream('statuses/sample.json', params, { autoConnect }); + } + /** + * Create a client that is prefixed with `https//stream.twitter.com` instead of classic API URL. + */ + get stream() { + const copiedClient = new client_v1_1.default(this); + copiedClient.setPrefix(globals_1.API_V1_1_STREAM_PREFIX); + return copiedClient; + } + /* Trends API */ + /** + * Returns the top 50 trending topics for a specific id, if trending information is available for it. + * Note: The id parameter for this endpoint is the "where on earth identifier" or WOEID, which is a legacy identifier created by Yahoo and has been deprecated. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/trends-for-location/api-reference/get-trends-place + */ + trendsByPlace(woeId, options = {}) { + return this.get('trends/place.json', { id: woeId, ...options }); + } + /** + * Returns the locations that Twitter has trending topic information for. + * The response is an array of "locations" that encode the location's WOEID + * and some other human-readable information such as a canonical name and country the location belongs in. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-available + */ + trendsAvailable() { + return this.get('trends/available.json'); + } + /** + * Returns the locations that Twitter has trending topic information for, closest to a specified location. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-closest + */ + trendsClosest(lat, long) { + return this.get('trends/closest.json', { lat, long }); + } + /* Geo API */ + /** + * Returns all the information about a known place. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/place-information/api-reference/get-geo-id-place_id + */ + geoPlace(placeId) { + return this.get('geo/id/:place_id.json', undefined, { params: { place_id: placeId } }); + } + /** + * Search for places that can be attached to a Tweet via POST statuses/update. + * This request will return a list of all the valid places that can be used as the place_id when updating a status. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-search + */ + geoSearch(options) { + return this.get('geo/search.json', options); + } + /** + * Given a latitude and a longitude, searches for up to 20 places that can be used as a place_id when updating a status. + * This request is an informative call and will deliver generalized results about geography. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-reverse_geocode + */ + geoReverseGeoCode(options) { + return this.get('geo/reverse_geocode.json', options); + } + /* Developer utilities */ + /** + * Returns the current rate limits for methods belonging to the specified resource families. + * Each API resource belongs to a "resource family" which is indicated in its method documentation. + * The method's resource family can be determined from the first component of the path after the resource version. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status + */ + rateLimitStatuses(...resources) { + return this.get('application/rate_limit_status.json', { resources }); + } + /** + * Returns the list of languages supported by Twitter along with the language code supported by Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/supported-languages/api-reference/get-help-languages + */ + supportedLanguages() { + return this.get('help/languages.json'); + } +} +exports.default = TwitterApiv1ReadOnly; diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.d.ts b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.d.ts new file mode 100644 index 0000000..8f91cde --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.d.ts @@ -0,0 +1,172 @@ +import { AccountProfileV1Params, AccountSettingsV1, AccountSettingsV1Params, AddOrRemoveListMembersV1Params, FriendshipCreateOrDestroyV1, FriendshipCreateV1Params, FriendshipDestroyV1Params, FriendshipUpdateV1Params, FriendshipV1, GetListV1Params, ListCreateV1Params, ListV1, MediaMetadataV1Params, MediaStatusV1Result, MediaSubtitleV1Param, ProfileBannerUpdateV1Params, ProfileImageUpdateV1Params, ReportSpamV1Params, SendTweetV1Params, TUploadableMedia, TweetV1, UpdateListV1Params, UploadMediaV1Params, UserV1 } from '../types'; +import TwitterApiv1ReadOnly from './client.v1.read'; +import { TFileHandle } from './media-helpers.v1'; +/** + * Base Twitter v1 client with read/write rights. + */ +export default class TwitterApiv1ReadWrite extends TwitterApiv1ReadOnly { + protected _prefix: string; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv1ReadOnly; + /** + * Post a new tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweet(status: string, payload?: Partial): Promise; + /** + * Quote an existing tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + quote(status: string, quotingStatusId: string, payload?: Partial): Promise; + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweetThread(tweets: (SendTweetV1Params | string)[]): Promise; + /** + * Reply to an existing tweet. Shortcut to `.tweet` with tweaked parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + reply(status: string, in_reply_to_status_id: string, payload?: Partial): Promise; + /** + * Delete an existing tweet belonging to you. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id + */ + deleteTweet(tweetId: string): Promise; + /** + * Report the specified user as a spam account to Twitter. + * Additionally, optionally performs the equivalent of POST blocks/create on behalf of the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam + */ + reportUserAsSpam(options: ReportSpamV1Params): Promise; + /** + * Turn on/off Retweets and device notifications from the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update + */ + updateFriendship(options: Partial): Promise; + /** + * Follow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create + */ + createFriendship(options: Partial): Promise; + /** + * Unfollow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy + */ + destroyFriendship(options: Partial): Promise; + /** + * Update current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + updateAccountSettings(options: Partial): Promise; + /** + * Sets some values that users are able to set under the "Account" tab of their settings page. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile + */ + updateAccountProfile(options: Partial): Promise; + /** + * Uploads a profile banner on behalf of the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_banner + */ + updateAccountProfileBanner(file: TUploadableMedia, options?: Partial): Promise; + /** + * Updates the authenticating user's profile image. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image + */ + updateAccountProfileImage(file: TUploadableMedia, options?: Partial): Promise; + /** + * Removes the uploaded profile banner for the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-remove_profile_banner + */ + removeAccountProfileBanner(): Promise; + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-create + */ + createList(options: ListCreateV1Params): Promise; + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-update + */ + updateList(options: UpdateListV1Params): Promise; + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy + */ + removeList(options: GetListV1Params): Promise; + /** + * Adds multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/create.json`, otherwise + * it will target `lists/members/create_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all + */ + addListMembers(options: AddOrRemoveListMembersV1Params): Promise; + /** + * Removes multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/destroy.json`, otherwise + * it will target `lists/members/destroy_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all + */ + removeListMembers(options: AddOrRemoveListMembersV1Params): Promise; + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create + */ + subscribeToList(options: GetListV1Params): Promise; + /** + * Unsubscribes the authenticated user of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy + */ + unsubscribeOfList(options: GetListV1Params): Promise; + /** + * This endpoint can be used to provide additional information about the uploaded media_id. + * This feature is currently only supported for images and GIFs. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-metadata-create + */ + createMediaMetadata(mediaId: string, metadata: Partial): Promise; + /** + * Use this endpoint to associate uploaded subtitles to an uploaded video. You can associate subtitles to video before or after Tweeting. + * **To obtain subtitle media ID, you must upload each subtitle file separately using `.uploadMedia()` method.** + * + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-create + */ + createMediaSubtitles(mediaId: string, subtitles: MediaSubtitleV1Param[]): Promise; + /** + * Use this endpoint to dissociate subtitles from a video and delete the subtitles. You can dissociate subtitles from a video before or after Tweeting. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-delete + */ + deleteMediaSubtitles(mediaId: string, ...languages: string[]): Promise; + /** + * Upload a media (JPG/PNG/GIF/MP4/MOV/WEBP) or subtitle (SRT) to Twitter and return the media_id to use in tweet/DM send. + * + * @param file If `string`, filename is supposed. + * A `Buffer` is a raw file. + * `fs.promises.FileHandle` or `number` are file pointers. + * + * @param options.type File type (Enum 'jpg' | 'longmp4' | 'mp4' | 'mov | 'png' | 'gif' | 'srt' | 'webp'). + * If filename is given, it could be guessed with file extension, otherwise this parameter is mandatory. + * If type is not part of the enum, it will be used as mime type. + * + * Type `longmp4` is **required** is you try to upload a video higher than 140 seconds. + * + * @param options.chunkLength Maximum chunk length sent to Twitter. Default goes to 1 MB. + * + * @param options.additionalOwners Other user IDs allowed to use the returned media_id. Default goes to none. + * + * @param options.maxConcurrentUploads Maximum uploaded chunks in the same time. Default goes to 3. + * + * @param options.target Target type `tweet` or `dm`. Defaults to `tweet`. + * You must specify it if you send a media to use in DMs. + */ + uploadMedia(file: TUploadableMedia, options?: Partial): Promise; + protected awaitForMediaProcessingCompletion(fullMediaData: MediaStatusV1Result): Promise; + protected getUploadMediaRequirements(file: TUploadableMedia, { mimeType, type, target, longVideo }?: Partial): Promise<{ + fileHandle: TFileHandle; + mediaCategory: string; + fileSize: number; + mimeType: string; + }>; + protected mediaChunkedUpload(fileHandle: TFileHandle, chunkLength: number, mediaId: string, maxConcurrentUploads?: number): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.js b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.js new file mode 100644 index 0000000..4140f94 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/client.v1.write.js @@ -0,0 +1,442 @@ +"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 }); +const fs = __importStar(require("fs")); +const globals_1 = require("../globals"); +const helpers_1 = require("../helpers"); +const types_1 = require("../types"); +const client_v1_read_1 = __importDefault(require("./client.v1.read")); +const media_helpers_v1_1 = require("./media-helpers.v1"); +const UPLOAD_ENDPOINT = 'media/upload.json'; +/** + * Base Twitter v1 client with read/write rights. + */ +class TwitterApiv1ReadWrite extends client_v1_read_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V1_1_PREFIX; + } + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } + /* Tweet API */ + /** + * Post a new tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweet(status, payload = {}) { + const queryParams = { + status, + tweet_mode: 'extended', + ...payload, + }; + return this.post('statuses/update.json', queryParams); + } + /** + * Quote an existing tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + async quote(status, quotingStatusId, payload = {}) { + const url = 'https://twitter.com/i/statuses/' + quotingStatusId; + return this.tweet(status, { ...payload, attachment_url: url }); + } + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + async tweetThread(tweets) { + const postedTweets = []; + for (const tweet of tweets) { + // Retrieve the last sent tweet + const lastTweet = postedTweets.length ? postedTweets[postedTweets.length - 1] : null; + // Build the tweet query params + const queryParams = { ...(typeof tweet === 'string' ? ({ status: tweet }) : tweet) }; + // Reply to an existing tweet if needed + const inReplyToId = lastTweet ? lastTweet.id_str : queryParams.in_reply_to_status_id; + const status = queryParams.status; + if (inReplyToId) { + postedTweets.push(await this.reply(status, inReplyToId, queryParams)); + } + else { + postedTweets.push(await this.tweet(status, queryParams)); + } + } + return postedTweets; + } + /** + * Reply to an existing tweet. Shortcut to `.tweet` with tweaked parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + reply(status, in_reply_to_status_id, payload = {}) { + return this.tweet(status, { + auto_populate_reply_metadata: true, + in_reply_to_status_id, + ...payload, + }); + } + /** + * Delete an existing tweet belonging to you. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id + */ + deleteTweet(tweetId) { + return this.post('statuses/destroy/:id.json', { tweet_mode: 'extended' }, { params: { id: tweetId } }); + } + /* User API */ + /** + * Report the specified user as a spam account to Twitter. + * Additionally, optionally performs the equivalent of POST blocks/create on behalf of the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam + */ + reportUserAsSpam(options) { + return this.post('users/report_spam.json', { tweet_mode: 'extended', ...options }); + } + /** + * Turn on/off Retweets and device notifications from the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update + */ + updateFriendship(options) { + return this.post('friendships/update.json', options); + } + /** + * Follow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create + */ + createFriendship(options) { + return this.post('friendships/create.json', options); + } + /** + * Unfollow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy + */ + destroyFriendship(options) { + return this.post('friendships/destroy.json', options); + } + /* Account API */ + /** + * Update current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + updateAccountSettings(options) { + return this.post('account/settings.json', options); + } + /** + * Sets some values that users are able to set under the "Account" tab of their settings page. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile + */ + updateAccountProfile(options) { + return this.post('account/update_profile.json', options); + } + /** + * Uploads a profile banner on behalf of the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_banner + */ + async updateAccountProfileBanner(file, options = {}) { + const queryParams = { + banner: await (0, media_helpers_v1_1.readFileIntoBuffer)(file), + ...options, + }; + return this.post('account/update_profile_banner.json', queryParams, { forceBodyMode: 'form-data' }); + } + /** + * Updates the authenticating user's profile image. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image + */ + async updateAccountProfileImage(file, options = {}) { + const queryParams = { + tweet_mode: 'extended', + image: await (0, media_helpers_v1_1.readFileIntoBuffer)(file), + ...options, + }; + return this.post('account/update_profile_image.json', queryParams, { forceBodyMode: 'form-data' }); + } + /** + * Removes the uploaded profile banner for the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-remove_profile_banner + */ + removeAccountProfileBanner() { + return this.post('account/remove_profile_banner.json'); + } + /* Lists */ + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-create + */ + createList(options) { + return this.post('lists/create.json', { tweet_mode: 'extended', ...options }); + } + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-update + */ + updateList(options) { + return this.post('lists/update.json', { tweet_mode: 'extended', ...options }); + } + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy + */ + removeList(options) { + return this.post('lists/destroy.json', { tweet_mode: 'extended', ...options }); + } + /** + * Adds multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/create.json`, otherwise + * it will target `lists/members/create_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all + */ + addListMembers(options) { + const hasMultiple = (options.user_id && (0, helpers_1.hasMultipleItems)(options.user_id)) || (options.screen_name && (0, helpers_1.hasMultipleItems)(options.screen_name)); + const endpoint = hasMultiple ? 'lists/members/create_all.json' : 'lists/members/create.json'; + return this.post(endpoint, options); + } + /** + * Removes multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/destroy.json`, otherwise + * it will target `lists/members/destroy_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all + */ + removeListMembers(options) { + const hasMultiple = (options.user_id && (0, helpers_1.hasMultipleItems)(options.user_id)) || (options.screen_name && (0, helpers_1.hasMultipleItems)(options.screen_name)); + const endpoint = hasMultiple ? 'lists/members/destroy_all.json' : 'lists/members/destroy.json'; + return this.post(endpoint, options); + } + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create + */ + subscribeToList(options) { + return this.post('lists/subscribers/create.json', { tweet_mode: 'extended', ...options }); + } + /** + * Unsubscribes the authenticated user of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy + */ + unsubscribeOfList(options) { + return this.post('lists/subscribers/destroy.json', { tweet_mode: 'extended', ...options }); + } + /* Media upload API */ + /** + * This endpoint can be used to provide additional information about the uploaded media_id. + * This feature is currently only supported for images and GIFs. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-metadata-create + */ + createMediaMetadata(mediaId, metadata) { + return this.post('media/metadata/create.json', { media_id: mediaId, ...metadata }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Use this endpoint to associate uploaded subtitles to an uploaded video. You can associate subtitles to video before or after Tweeting. + * **To obtain subtitle media ID, you must upload each subtitle file separately using `.uploadMedia()` method.** + * + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-create + */ + createMediaSubtitles(mediaId, subtitles) { + return this.post('media/subtitles/create.json', { media_id: mediaId, media_category: 'TweetVideo', subtitle_info: { subtitles } }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Use this endpoint to dissociate subtitles from a video and delete the subtitles. You can dissociate subtitles from a video before or after Tweeting. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-delete + */ + deleteMediaSubtitles(mediaId, ...languages) { + return this.post('media/subtitles/delete.json', { + media_id: mediaId, + media_category: 'TweetVideo', + subtitle_info: { subtitles: languages.map(lang => ({ language_code: lang })) }, + }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Upload a media (JPG/PNG/GIF/MP4/MOV/WEBP) or subtitle (SRT) to Twitter and return the media_id to use in tweet/DM send. + * + * @param file If `string`, filename is supposed. + * A `Buffer` is a raw file. + * `fs.promises.FileHandle` or `number` are file pointers. + * + * @param options.type File type (Enum 'jpg' | 'longmp4' | 'mp4' | 'mov | 'png' | 'gif' | 'srt' | 'webp'). + * If filename is given, it could be guessed with file extension, otherwise this parameter is mandatory. + * If type is not part of the enum, it will be used as mime type. + * + * Type `longmp4` is **required** is you try to upload a video higher than 140 seconds. + * + * @param options.chunkLength Maximum chunk length sent to Twitter. Default goes to 1 MB. + * + * @param options.additionalOwners Other user IDs allowed to use the returned media_id. Default goes to none. + * + * @param options.maxConcurrentUploads Maximum uploaded chunks in the same time. Default goes to 3. + * + * @param options.target Target type `tweet` or `dm`. Defaults to `tweet`. + * You must specify it if you send a media to use in DMs. + */ + async uploadMedia(file, options = {}) { + var _a; + const chunkLength = (_a = options.chunkLength) !== null && _a !== void 0 ? _a : (1024 * 1024); + const { fileHandle, mediaCategory, fileSize, mimeType } = await this.getUploadMediaRequirements(file, options); + // Get the file handle (if not buffer) + try { + // Finally! We can send INIT message. + const mediaData = await this.post(UPLOAD_ENDPOINT, { + command: 'INIT', + total_bytes: fileSize, + media_type: mimeType, + media_category: mediaCategory, + additional_owners: options.additionalOwners, + shared: options.shared ? true : undefined, + }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX }); + // Upload the media chunk by chunk + await this.mediaChunkedUpload(fileHandle, chunkLength, mediaData.media_id_string, options.maxConcurrentUploads); + // Finalize media + const fullMediaData = await this.post(UPLOAD_ENDPOINT, { + command: 'FINALIZE', + media_id: mediaData.media_id_string, + }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX }); + if (fullMediaData.processing_info && fullMediaData.processing_info.state !== 'succeeded') { + // Must wait if video is still computed + await this.awaitForMediaProcessingCompletion(fullMediaData); + } + // Video is ready, return media_id + return fullMediaData.media_id_string; + } + finally { + // Close file if any + if (typeof file === 'number') { + // eslint-disable-next-line @typescript-eslint/no-empty-function + fs.close(file, () => { }); + } + else if (typeof fileHandle === 'object' && !(fileHandle instanceof Buffer)) { + fileHandle.close(); + } + } + } + async awaitForMediaProcessingCompletion(fullMediaData) { + // eslint-disable-next-line no-constant-condition + while (true) { + fullMediaData = await this.mediaInfo(fullMediaData.media_id_string); + const { processing_info } = fullMediaData; + if (!processing_info || processing_info.state === 'succeeded') { + // Ok, completed! + return; + } + if (processing_info.state === 'failed') { + if (processing_info.error) { + const { name, message } = processing_info.error; + throw new Error(`Failed to process media: ${name} - ${message}.`); + } + throw new Error('Failed to process the media.'); + } + if (processing_info.check_after_secs) { + // Await for given seconds + await (0, media_helpers_v1_1.sleepSecs)(processing_info.check_after_secs); + } + else { + // No info; Await for 5 seconds + await (0, media_helpers_v1_1.sleepSecs)(5); + } + } + } + async getUploadMediaRequirements(file, { mimeType, type, target, longVideo } = {}) { + // Get the file handle (if not buffer) + let fileHandle; + try { + fileHandle = await (0, media_helpers_v1_1.getFileHandle)(file); + // Get the mimetype + const realMimeType = (0, media_helpers_v1_1.getMimeType)(file, type, mimeType); + // Get the media category + let mediaCategory; + // If explicit longmp4 OR explicit MIME type and not DM target + if (realMimeType === types_1.EUploadMimeType.Mp4 && ((!mimeType && !type && target !== 'dm') || longVideo)) { + mediaCategory = 'amplify_video'; + } + else { + mediaCategory = (0, media_helpers_v1_1.getMediaCategoryByMime)(realMimeType, target !== null && target !== void 0 ? target : 'tweet'); + } + return { + fileHandle, + mediaCategory, + fileSize: await (0, media_helpers_v1_1.getFileSizeFromFileHandle)(fileHandle), + mimeType: realMimeType, + }; + } + catch (e) { + // Close file if any + if (typeof file === 'number') { + // eslint-disable-next-line @typescript-eslint/no-empty-function + fs.close(file, () => { }); + } + else if (typeof fileHandle === 'object' && !(fileHandle instanceof Buffer)) { + fileHandle.close(); + } + throw e; + } + } + async mediaChunkedUpload(fileHandle, chunkLength, mediaId, maxConcurrentUploads = 3) { + // Send chunk by chunk + let chunkIndex = 0; + if (maxConcurrentUploads < 1) { + throw new RangeError('Bad maxConcurrentUploads parameter.'); + } + // Creating a buffer for doing file stuff (if we don't have one) + const buffer = fileHandle instanceof Buffer ? undefined : Buffer.alloc(chunkLength); + // Sliced/filled buffer returned for each part + let readBuffer; + // Needed to know when we should stop reading the file + let nread; + // Needed to use the buffer object (file handles always "remembers" file position) + let offset = 0; + [readBuffer, nread] = await (0, media_helpers_v1_1.readNextPartOf)(fileHandle, chunkLength, offset, buffer); + offset += nread; + // Handle max concurrent uploads + const currentUploads = new Set(); + // Read buffer until file is completely read + while (nread) { + const mediaBufferPart = readBuffer.slice(0, nread); + // Sent part if part has something inside + if (mediaBufferPart.length) { + const request = this.post(UPLOAD_ENDPOINT, { + command: 'APPEND', + media_id: mediaId, + segment_index: chunkIndex, + media: mediaBufferPart, + }, { prefix: globals_1.API_V1_1_UPLOAD_PREFIX }); + currentUploads.add(request); + request.then(() => { + currentUploads.delete(request); + }); + chunkIndex++; + } + if (currentUploads.size >= maxConcurrentUploads) { + // Await for first promise to be finished + await Promise.race(currentUploads); + } + [readBuffer, nread] = await (0, media_helpers_v1_1.readNextPartOf)(fileHandle, chunkLength, offset, buffer); + offset += nread; + } + await Promise.all([...currentUploads]); + } +} +exports.default = TwitterApiv1ReadWrite; diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.d.ts b/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.d.ts new file mode 100644 index 0000000..f786bdd --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.d.ts @@ -0,0 +1,13 @@ +/// +/// +import * as fs from 'fs'; +import type { TUploadableMedia, TUploadTypeV1 } from '../types'; +import { EUploadMimeType } from '../types'; +export declare type TFileHandle = fs.promises.FileHandle | number | Buffer; +export declare function readFileIntoBuffer(file: TUploadableMedia): Promise; +export declare function getFileHandle(file: TUploadableMedia): number | Buffer | fs.promises.FileHandle | Promise; +export declare function getFileSizeFromFileHandle(fileHandle: TFileHandle): Promise; +export declare function getMimeType(file: TUploadableMedia, type?: TUploadTypeV1 | string, mimeType?: EUploadMimeType | string): string; +export declare function getMediaCategoryByMime(name: string, target: 'tweet' | 'dm'): "TweetVideo" | "DmVideo" | "TweetGif" | "DmGif" | "Subtitles" | "TweetImage" | "DmImage"; +export declare function sleepSecs(seconds: number): Promise; +export declare function readNextPartOf(file: TFileHandle, chunkLength: number, bufferOffset?: number, buffer?: Buffer): Promise<[Buffer, number]>; diff --git a/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.js b/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.js new file mode 100644 index 0000000..1a4ad70 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v1/media-helpers.v1.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.readNextPartOf = exports.sleepSecs = exports.getMediaCategoryByMime = exports.getMimeType = exports.getFileSizeFromFileHandle = exports.getFileHandle = exports.readFileIntoBuffer = void 0; +const fs = __importStar(require("fs")); +const helpers_1 = require("../helpers"); +const types_1 = require("../types"); +async function readFileIntoBuffer(file) { + const handle = await getFileHandle(file); + if (typeof handle === 'number') { + return new Promise((resolve, reject) => { + fs.readFile(handle, (err, data) => { + if (err) { + return reject(err); + } + resolve(data); + }); + }); + } + else if (handle instanceof Buffer) { + return handle; + } + else { + return handle.readFile(); + } +} +exports.readFileIntoBuffer = readFileIntoBuffer; +function getFileHandle(file) { + if (typeof file === 'string') { + return fs.promises.open(file, 'r'); + } + else if (typeof file === 'number') { + return file; + } + else if (typeof file === 'object' && !(file instanceof Buffer)) { + return file; + } + else if (!(file instanceof Buffer)) { + throw new Error('Given file is not valid, please check its type.'); + } + else { + return file; + } +} +exports.getFileHandle = getFileHandle; +async function getFileSizeFromFileHandle(fileHandle) { + // Get the file size + if (typeof fileHandle === 'number') { + const stats = await new Promise((resolve, reject) => { + fs.fstat(fileHandle, (err, stats) => { + if (err) + reject(err); + resolve(stats); + }); + }); + return stats.size; + } + else if (fileHandle instanceof Buffer) { + return fileHandle.length; + } + else { + return (await fileHandle.stat()).size; + } +} +exports.getFileSizeFromFileHandle = getFileSizeFromFileHandle; +function getMimeType(file, type, mimeType) { + if (typeof mimeType === 'string') { + return mimeType; + } + else if (typeof file === 'string' && !type) { + return getMimeByName(file); + } + else if (typeof type === 'string') { + return getMimeByType(type); + } + throw new Error('You must specify type if file is a file handle or Buffer.'); +} +exports.getMimeType = getMimeType; +function getMimeByName(name) { + if (name.endsWith('.jpeg') || name.endsWith('.jpg')) + return types_1.EUploadMimeType.Jpeg; + if (name.endsWith('.png')) + return types_1.EUploadMimeType.Png; + if (name.endsWith('.webp')) + return types_1.EUploadMimeType.Webp; + if (name.endsWith('.gif')) + return types_1.EUploadMimeType.Gif; + if (name.endsWith('.mpeg4') || name.endsWith('.mp4')) + return types_1.EUploadMimeType.Mp4; + if (name.endsWith('.mov') || name.endsWith('.mov')) + return types_1.EUploadMimeType.Mov; + if (name.endsWith('.srt')) + return types_1.EUploadMimeType.Srt; + (0, helpers_1.safeDeprecationWarning)({ + instance: 'TwitterApiv1ReadWrite', + method: 'uploadMedia', + problem: 'options.mimeType is missing and filename couldn\'t help to resolve MIME type, so it will fallback to image/jpeg', + resolution: 'If you except to give filenames without extensions, please specify explicitlty the MIME type using options.mimeType', + }); + return types_1.EUploadMimeType.Jpeg; +} +function getMimeByType(type) { + (0, helpers_1.safeDeprecationWarning)({ + instance: 'TwitterApiv1ReadWrite', + method: 'uploadMedia', + problem: 'you\'re using options.type', + resolution: 'Remove options.type argument and migrate to options.mimeType which takes the real MIME type. ' + + 'If you\'re using type=longmp4, add options.longVideo alongside of mimeType=EUploadMimeType.Mp4', + }); + if (type === 'gif') + return types_1.EUploadMimeType.Gif; + if (type === 'jpg') + return types_1.EUploadMimeType.Jpeg; + if (type === 'png') + return types_1.EUploadMimeType.Png; + if (type === 'webp') + return types_1.EUploadMimeType.Webp; + if (type === 'srt') + return types_1.EUploadMimeType.Srt; + if (type === 'mp4' || type === 'longmp4') + return types_1.EUploadMimeType.Mp4; + if (type === 'mov') + return types_1.EUploadMimeType.Mov; + return type; +} +function getMediaCategoryByMime(name, target) { + if (name === types_1.EUploadMimeType.Mp4 || name === types_1.EUploadMimeType.Mov) + return target === 'tweet' ? 'TweetVideo' : 'DmVideo'; + if (name === types_1.EUploadMimeType.Gif) + return target === 'tweet' ? 'TweetGif' : 'DmGif'; + if (name === types_1.EUploadMimeType.Srt) + return 'Subtitles'; + else + return target === 'tweet' ? 'TweetImage' : 'DmImage'; +} +exports.getMediaCategoryByMime = getMediaCategoryByMime; +function sleepSecs(seconds) { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)); +} +exports.sleepSecs = sleepSecs; +async function readNextPartOf(file, chunkLength, bufferOffset = 0, buffer) { + if (file instanceof Buffer) { + const rt = file.slice(bufferOffset, bufferOffset + chunkLength); + return [rt, rt.length]; + } + if (!buffer) { + throw new Error('Well, we will need a buffer to store file content.'); + } + let bytesRead; + if (typeof file === 'number') { + bytesRead = await new Promise((resolve, reject) => { + fs.read(file, buffer, 0, chunkLength, bufferOffset, (err, nread) => { + if (err) + reject(err); + resolve(nread); + }); + }); + } + else { + const res = await file.read(buffer, 0, chunkLength, bufferOffset); + bytesRead = res.bytesRead; + } + return [buffer, bytesRead]; +} +exports.readNextPartOf = readNextPartOf; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.d.ts new file mode 100644 index 0000000..fe37424 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.d.ts @@ -0,0 +1,12 @@ +import TwitterApiv2LabsReadWrite from './client.v2.labs.write'; +/** + * Twitter v2 labs client with all rights (read/write/DMs) + */ +export declare class TwitterApiv2Labs extends TwitterApiv2LabsReadWrite { + protected _prefix: string; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv2LabsReadWrite; +} +export default TwitterApiv2Labs; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.js b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.js new file mode 100644 index 0000000..eb0b00b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.js @@ -0,0 +1,25 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TwitterApiv2Labs = void 0; +const globals_1 = require("../globals"); +const client_v2_labs_write_1 = __importDefault(require("./client.v2.labs.write")); +/** + * Twitter v2 labs client with all rights (read/write/DMs) + */ +class TwitterApiv2Labs extends client_v2_labs_write_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_LABS_PREFIX; + } + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } +} +exports.TwitterApiv2Labs = TwitterApiv2Labs; +exports.default = TwitterApiv2Labs; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.d.ts new file mode 100644 index 0000000..fb79198 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.d.ts @@ -0,0 +1,7 @@ +import TwitterApiSubClient from '../client.subclient'; +/** + * Base Twitter v2 labs client with only read right. + */ +export default class TwitterApiv2LabsReadOnly extends TwitterApiSubClient { + protected _prefix: string; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.js b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.js new file mode 100644 index 0000000..4cd8c95 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.read.js @@ -0,0 +1,17 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const client_subclient_1 = __importDefault(require("../client.subclient")); +const globals_1 = require("../globals"); +/** + * Base Twitter v2 labs client with only read right. + */ +class TwitterApiv2LabsReadOnly extends client_subclient_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_LABS_PREFIX; + } +} +exports.default = TwitterApiv2LabsReadOnly; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.d.ts new file mode 100644 index 0000000..d546f64 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.d.ts @@ -0,0 +1,11 @@ +import TwitterApiv2LabsReadOnly from './client.v2.labs.read'; +/** + * Base Twitter v2 labs client with read/write rights. + */ +export default class TwitterApiv2LabsReadWrite extends TwitterApiv2LabsReadOnly { + protected _prefix: string; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv2LabsReadOnly; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.js b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.js new file mode 100644 index 0000000..acef13e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2-labs/client.v2.labs.write.js @@ -0,0 +1,23 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const globals_1 = require("../globals"); +const client_v2_labs_read_1 = __importDefault(require("./client.v2.labs.read")); +/** + * Base Twitter v2 labs client with read/write rights. + */ +class TwitterApiv2LabsReadWrite extends client_v2_labs_read_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_LABS_PREFIX; + } + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } +} +exports.default = TwitterApiv2LabsReadWrite; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.d.ts new file mode 100644 index 0000000..9caf1a0 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.d.ts @@ -0,0 +1,18 @@ +import TwitterApiv2ReadWrite from './client.v2.write'; +import TwitterApiv2Labs from '../v2-labs/client.v2.labs'; +/** + * Twitter v2 client with all rights (read/write/DMs) + */ +export declare class TwitterApiv2 extends TwitterApiv2ReadWrite { + protected _prefix: string; + protected _labs?: TwitterApiv2Labs; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv2ReadWrite; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2Labs; +} +export default TwitterApiv2; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.js b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.js new file mode 100644 index 0000000..639a974 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.js @@ -0,0 +1,36 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TwitterApiv2 = void 0; +const globals_1 = require("../globals"); +const client_v2_write_1 = __importDefault(require("./client.v2.write")); +const client_v2_labs_1 = __importDefault(require("../v2-labs/client.v2.labs")); +/** + * Twitter v2 client with all rights (read/write/DMs) + */ +class TwitterApiv2 extends client_v2_write_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_PREFIX; + /** API endpoints */ + } + /* Sub-clients */ + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new client_v2_labs_1.default(this); + } +} +exports.TwitterApiv2 = TwitterApiv2; +exports.default = TwitterApiv2; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.d.ts new file mode 100644 index 0000000..d9f2637 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.d.ts @@ -0,0 +1,352 @@ +import TwitterApiSubClient from '../client.subclient'; +import { Tweetv2FieldsParams, Tweetv2SearchParams, UserV2Result, UsersV2Result, UsersV2Params, StreamingV2GetRulesParams, StreamingV2GetRulesResult, TweetV2LookupResult, TweetV2UserTimelineParams, StreamingV2AddRulesParams, StreamingV2DeleteRulesParams, StreamingV2UpdateRulesQuery, StreamingV2UpdateRulesDeleteResult, StreamingV2UpdateRulesAddResult, TweetV2SingleResult, TweetV2PaginableTimelineParams, TweetV2CountResult, TweetV2CountParams, TweetV2CountAllResult, TweetV2CountAllParams, TweetV2RetweetedByResult, TweetV2LikedByResult, UserV2TimelineParams, UserV2TimelineResult, FollowersV2ParamsWithPaginator, FollowersV2ParamsWithoutPaginator, TweetSearchV2StreamParams, TweetV2SingleStreamResult, TweetV2PaginableListParams, SpaceV2FieldsParams, SpaceV2LookupResult, SpaceV2CreatorLookupParams, SpaceV2SearchParams, SpaceV2SingleResult, BatchComplianceSearchV2Params, BatchComplianceListV2Result, BatchComplianceV2Result, BatchComplianceV2Params, BatchComplianceV2JobResult, BatchComplianceJobV2, GetListV2Params, ListGetV2Result, GetListTimelineV2Params, TweetRetweetedOrLikedByV2ParamsWithPaginator, TweetRetweetedOrLikedByV2ParamsWithoutPaginator, SpaceV2BuyersParams, TweetV2HomeTimelineParams } from '../types'; +import { TweetSearchAllV2Paginator, TweetSearchRecentV2Paginator, TweetUserMentionTimelineV2Paginator, TweetUserTimelineV2Paginator, TweetV2UserLikedTweetsPaginator, UserOwnedListsV2Paginator, UserListMembershipsV2Paginator, UserListFollowedV2Paginator, TweetV2ListTweetsPaginator, TweetBookmarksTimelineV2Paginator, QuotedTweetsTimelineV2Paginator, TweetHomeTimelineV2Paginator } from '../paginators'; +import TwitterApiv2LabsReadOnly from '../v2-labs/client.v2.labs.read'; +import { TweetLikingUsersV2Paginator, TweetRetweetersUsersV2Paginator, UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator, UserListFollowersV2Paginator, UserListMembersV2Paginator, UserMutingUsersV2Paginator } from '../paginators/user.paginator.v2'; +import TweetStream from '../stream/TweetStream'; +import { PromiseOrType } from '../types/shared.types'; +import { GetDMEventV2Params } from '../types/v2/dm.v2.types'; +import { ConversationDMTimelineV2Paginator, FullDMTimelineV2Paginator, OneToOneDMTimelineV2Paginator } from '../paginators/dm.paginator.v2'; +/** + * Base Twitter v2 client with only read right. + */ +export default class TwitterApiv2ReadOnly extends TwitterApiSubClient { + protected _prefix: string; + protected _labs?: TwitterApiv2LabsReadOnly; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2LabsReadOnly; + /** + * The recent search endpoint returns Tweets from the last seven days that match a search query. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent + */ + search(options: Tweetv2SearchParams): Promise; + search(query: string, options?: Partial): Promise; + /** + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all + */ + searchAll(query: string, options?: Partial): Promise; + /** + * Returns a variety of information about a single Tweet specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + singleTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns a variety of information about tweets specified by list of IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + tweets(tweetIds: string | string[], options?: Partial): Promise; + /** + * The recent Tweet counts endpoint returns count of Tweets from the last seven days that match a search query. + * OAuth2 Bearer auth only. + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + */ + tweetCountRecent(query: string, options?: Partial): Promise; + /** + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * OAuth2 Bearer auth only. + * **This endpoint has pagination, yet it is not supported by bundled paginators. Use `next_token` to fetch next page.** + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + */ + tweetCountAll(query: string, options?: Partial): Promise; + /** + * Allows you to get information about who has Retweeted a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/get-tweets-id-retweeted_by + */ + tweetRetweetedBy(tweetId: string, options?: Partial): Promise; + tweetRetweetedBy(tweetId: string, options: TweetRetweetedOrLikedByV2ParamsWithPaginator): Promise; + /** + * Allows you to get information about who has Liked a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users + */ + tweetLikedBy(tweetId: string, options?: Partial): Promise; + tweetLikedBy(tweetId: string, options: TweetRetweetedOrLikedByV2ParamsWithPaginator): Promise; + /** + * Allows you to retrieve a collection of the most recent Tweets and Retweets posted by you and users you follow, also known as home timeline. + * This endpoint returns up to the last 3200 Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological + * + * OAuth 2 scopes: `tweet.read` `users.read` + */ + homeTimeline(options?: Partial): Promise; + /** + * Returns Tweets composed by a single user, specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, the most recent 3,200 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + */ + userTimeline(userId: string, options?: Partial): Promise; + /** + * Returns Tweets mentioning a single user specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, up to the most recent 800 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions + */ + userMentionTimeline(userId: string, options?: Partial): Promise; + /** + * Returns Quote Tweets for a Tweet specified by the requested Tweet ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets + * + * OAuth2 scopes: `users.read` `tweet.read` + */ + quotes(tweetId: string, options?: Partial): Promise; + /** + * Allows you to get information about a authenticated user’s 800 most recent bookmarked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.read` + */ + bookmarks(options?: Partial): Promise; + /** + * Returns information about an authorized user. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me + * + * OAuth2 scopes: `tweet.read` & `users.read` + */ + me(options?: Partial): Promise; + /** + * Returns a variety of information about a single user specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-id + */ + user(userId: string, options?: Partial): Promise; + /** + * Returns a variety of information about one or more users specified by the requested IDs. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users + */ + users(userIds: string | string[], options?: Partial): Promise; + /** + * Returns a variety of information about a single user specified by their username. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username + */ + userByUsername(username: string, options?: Partial): Promise; + /** + * Returns a variety of information about one or more users specified by their usernames. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + usersByUsernames(usernames: string | string[], options?: Partial): Promise; + /** + * Returns a list of users who are followers of the specified user ID. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers + */ + followers(userId: string, options?: Partial): Promise; + followers(userId: string, options: FollowersV2ParamsWithPaginator): Promise; + /** + * Returns a list of users the specified user ID is following. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-following + * + * OAuth2 scope: `follows.read` + */ + following(userId: string, options?: Partial): Promise; + following(userId: string, options: FollowersV2ParamsWithPaginator): Promise; + /** + * Allows you to get information about a user’s liked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + */ + userLikedTweets(userId: string, options?: Partial): Promise; + /** + * Returns a list of users who are blocked by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + */ + userBlockingUsers(userId: string, options?: Partial): Promise; + /** + * Returns a list of users who are muted by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting + */ + userMutingUsers(userId: string, options?: Partial): Promise; + /** + * Returns the details of a specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + */ + list(id: string, options?: Partial): Promise; + /** + * Returns all Lists owned by the specified user. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists + */ + listsOwned(userId: string, options?: Partial): Promise; + /** + * Returns all Lists a specified user is a member of. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-users-id-list_memberships + */ + listMemberships(userId: string, options?: Partial): Promise; + /** + * Returns all Lists a specified user follows. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-users-id-followed_lists + */ + listFollowed(userId: string, options?: Partial): Promise; + /** + * Returns a list of Tweets from the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-tweets/api-reference/get-lists-id-tweets + */ + listTweets(listId: string, options?: Partial): Promise; + /** + * Returns a list of users who are members of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-lists-id-members + */ + listMembers(listId: string, options?: Partial): Promise; + /** + * Returns a list of users who are followers of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-lists-id-followers + */ + listFollowers(listId: string, options?: Partial): Promise; + /** + * Returns a list of Direct Messages for the authenticated user, both sent and received. + * Direct Message events are returned in reverse chronological order. + * Supports retrieving events from the previous 30 days. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_events + */ + listDmEvents(options?: Partial): Promise; + /** + * Returns a list of Direct Messages (DM) events within a 1-1 conversation with the user specified in the participant_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + listDmEventsWithParticipant(participantId: string, options?: Partial): Promise; + /** + * Returns a list of Direct Messages within a conversation specified in the dm_conversation_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + listDmEventsOfConversation(dmConversationId: string, options?: Partial): Promise; + /** + * Get a single space by ID. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + space(spaceId: string, options?: Partial): Promise; + /** + * Get spaces using their IDs. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaces(spaceIds: string | string[], options?: Partial): Promise; + /** + * Get spaces using their creator user ID(s). (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spacesByCreators(creatorIds: string | string[], options?: Partial): Promise; + /** + * Search through spaces using multiple params. (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search + */ + searchSpaces(options: SpaceV2SearchParams): Promise; + /** + * Returns a list of user who purchased a ticket to the requested Space. + * You must authenticate the request using the Access Token of the creator of the requested Space. + * + * **OAuth 2.0 Access Token required** + * + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-buyers + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaceBuyers(spaceId: string, options?: Partial): Promise; + /** + * Returns Tweets shared in the requested Spaces. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-tweets + * + * OAuth2 scope: `users.read`, `tweet.read`, `space.read` + */ + spaceTweets(spaceId: string, options?: Partial): Promise; + /** + * Streams Tweets in real-time based on a specific set of filter rules. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream + */ + searchStream(options?: Partial & { + autoConnect?: true; + }): Promise>; + searchStream(options: Partial & { + autoConnect: false; + }): TweetStream; + searchStream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Return a list of rules currently active on the streaming endpoint, either as a list or individually. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules + */ + streamRules(options?: Partial): Promise; + /** + * Add or delete rules to your stream. + * To create one or more rules, submit an add JSON body with an array of rules and operators. + * Similarly, to delete one or more rules, submit a delete JSON body with an array of list of existing rule IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules + */ + updateStreamRules(options: StreamingV2AddRulesParams, query?: Partial): Promise; + updateStreamRules(options: StreamingV2DeleteRulesParams, query?: Partial): Promise; + /** + * Streams about 1% of all Tweets in real-time. + * https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream + */ + sampleStream(options?: Partial & { + autoConnect?: true; + }): Promise>; + sampleStream(options: Partial & { + autoConnect: false; + }): TweetStream; + sampleStream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Streams about 10% of all Tweets in real-time. + * https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample10-stream + */ + sample10Stream(options?: Partial & { + autoConnect?: true; + }): Promise>; + sample10Stream(options: Partial & { + autoConnect: false; + }): TweetStream; + sample10Stream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Returns a list of recent compliance jobs. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs + */ + complianceJobs(options: BatchComplianceSearchV2Params): Promise; + /** + * Get a single compliance job with the specified ID. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs-id + */ + complianceJob(jobId: string): Promise; + /** + * Creates a new compliance job for Tweet IDs or user IDs, send your file, await result and parse it into an array. + * You can run one batch job at a time. Returns the created job, but **not the job result!**. + * + * You can obtain the result (**after job is completed**) with `.complianceJobResult`. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + sendComplianceJob(jobParams: BatchComplianceV2Params): Promise; + /** + * Get the result of a running or completed job, obtained through `.complianceJob`, `.complianceJobs` or `.sendComplianceJob`. + * If job is still running (`in_progress`), it will await until job is completed. **This could be quite long!** + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + complianceJobResult(job: BatchComplianceJobV2): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.js b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.js new file mode 100644 index 0000000..e12f5fb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.read.js @@ -0,0 +1,638 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const client_subclient_1 = __importDefault(require("../client.subclient")); +const globals_1 = require("../globals"); +const paginators_1 = require("../paginators"); +const client_v2_labs_read_1 = __importDefault(require("../v2-labs/client.v2.labs.read")); +const user_paginator_v2_1 = require("../paginators/user.paginator.v2"); +const helpers_1 = require("../helpers"); +const dm_paginator_v2_1 = require("../paginators/dm.paginator.v2"); +/** + * Base Twitter v2 client with only read right. + */ +class TwitterApiv2ReadOnly extends client_subclient_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_PREFIX; + } + /* Sub-clients */ + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new client_v2_labs_read_1.default(this); + } + async search(queryOrOptions, options = {}) { + const queryParams = typeof queryOrOptions === 'string' ? + { ...options, query: queryOrOptions } : + { ...queryOrOptions }; + const initialRq = await this.get('tweets/search/recent', queryParams, { fullResponse: true }); + return new paginators_1.TweetSearchRecentV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all + */ + async searchAll(query, options = {}) { + const queryParams = { ...options, query }; + const initialRq = await this.get('tweets/search/all', queryParams, { fullResponse: true }); + return new paginators_1.TweetSearchAllV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a variety of information about a single Tweet specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + singleTweet(tweetId, options = {}) { + return this.get('tweets/:id', options, { params: { id: tweetId } }); + } + /** + * Returns a variety of information about tweets specified by list of IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + tweets(tweetIds, options = {}) { + return this.get('tweets', { ids: tweetIds, ...options }); + } + /** + * The recent Tweet counts endpoint returns count of Tweets from the last seven days that match a search query. + * OAuth2 Bearer auth only. + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + */ + tweetCountRecent(query, options = {}) { + return this.get('tweets/counts/recent', { query, ...options }); + } + /** + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * OAuth2 Bearer auth only. + * **This endpoint has pagination, yet it is not supported by bundled paginators. Use `next_token` to fetch next page.** + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + */ + tweetCountAll(query, options = {}) { + return this.get('tweets/counts/all', { query, ...options }); + } + async tweetRetweetedBy(tweetId, options = {}) { + const { asPaginator, ...parameters } = options; + const initialRq = await this.get('tweets/:id/retweeted_by', parameters, { + fullResponse: true, + params: { id: tweetId }, + }); + if (!asPaginator) { + return initialRq.data; + } + return new user_paginator_v2_1.TweetRetweetersUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: { id: tweetId }, + }); + } + async tweetLikedBy(tweetId, options = {}) { + const { asPaginator, ...parameters } = options; + const initialRq = await this.get('tweets/:id/liking_users', parameters, { + fullResponse: true, + params: { id: tweetId }, + }); + if (!asPaginator) { + return initialRq.data; + } + return new user_paginator_v2_1.TweetLikingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: { id: tweetId }, + }); + } + /** + * Allows you to retrieve a collection of the most recent Tweets and Retweets posted by you and users you follow, also known as home timeline. + * This endpoint returns up to the last 3200 Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological + * + * OAuth 2 scopes: `tweet.read` `users.read` + */ + async homeTimeline(options = {}) { + const meUser = await this.getCurrentUserV2Object(); + const initialRq = await this.get('users/:id/timelines/reverse_chronological', options, { + fullResponse: true, + params: { id: meUser.data.id }, + }); + return new paginators_1.TweetHomeTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: meUser.data.id }, + }); + } + /** + * Returns Tweets composed by a single user, specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, the most recent 3,200 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + */ + async userTimeline(userId, options = {}) { + const initialRq = await this.get('users/:id/tweets', options, { + fullResponse: true, + params: { id: userId }, + }); + return new paginators_1.TweetUserTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: userId }, + }); + } + /** + * Returns Tweets mentioning a single user specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, up to the most recent 800 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions + */ + async userMentionTimeline(userId, options = {}) { + const initialRq = await this.get('users/:id/mentions', options, { + fullResponse: true, + params: { id: userId }, + }); + return new paginators_1.TweetUserMentionTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: userId }, + }); + } + /** + * Returns Quote Tweets for a Tweet specified by the requested Tweet ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets + * + * OAuth2 scopes: `users.read` `tweet.read` + */ + async quotes(tweetId, options = {}) { + const initialRq = await this.get('tweets/:id/quote_tweets', options, { + fullResponse: true, + params: { id: tweetId }, + }); + return new paginators_1.QuotedTweetsTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: tweetId }, + }); + } + /* Bookmarks */ + /** + * Allows you to get information about a authenticated user’s 800 most recent bookmarked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.read` + */ + async bookmarks(options = {}) { + const user = await this.getCurrentUserV2Object(); + const initialRq = await this.get('users/:id/bookmarks', options, { + fullResponse: true, + params: { id: user.data.id }, + }); + return new paginators_1.TweetBookmarksTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: user.data.id }, + }); + } + /* Users */ + /** + * Returns information about an authorized user. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me + * + * OAuth2 scopes: `tweet.read` & `users.read` + */ + me(options = {}) { + return this.get('users/me', options); + } + /** + * Returns a variety of information about a single user specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-id + */ + user(userId, options = {}) { + return this.get('users/:id', options, { params: { id: userId } }); + } + /** + * Returns a variety of information about one or more users specified by the requested IDs. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users + */ + users(userIds, options = {}) { + const ids = Array.isArray(userIds) ? userIds.join(',') : userIds; + return this.get('users', { ...options, ids }); + } + /** + * Returns a variety of information about a single user specified by their username. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username + */ + userByUsername(username, options = {}) { + return this.get('users/by/username/:username', options, { params: { username } }); + } + /** + * Returns a variety of information about one or more users specified by their usernames. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + usersByUsernames(usernames, options = {}) { + usernames = Array.isArray(usernames) ? usernames.join(',') : usernames; + return this.get('users/by', { ...options, usernames }); + } + async followers(userId, options = {}) { + const { asPaginator, ...parameters } = options; + const params = { id: userId }; + if (!asPaginator) { + return this.get('users/:id/followers', parameters, { params }); + } + const initialRq = await this.get('users/:id/followers', parameters, { fullResponse: true, params }); + return new user_paginator_v2_1.UserFollowersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: params, + }); + } + async following(userId, options = {}) { + const { asPaginator, ...parameters } = options; + const params = { id: userId }; + if (!asPaginator) { + return this.get('users/:id/following', parameters, { params }); + } + const initialRq = await this.get('users/:id/following', parameters, { fullResponse: true, params }); + return new user_paginator_v2_1.UserFollowingV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: params, + }); + } + /** + * Allows you to get information about a user’s liked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + */ + async userLikedTweets(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/liked_tweets', options, { fullResponse: true, params }); + return new paginators_1.TweetV2UserLikedTweetsPaginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are blocked by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + */ + async userBlockingUsers(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/blocking', options, { fullResponse: true, params }); + return new user_paginator_v2_1.UserBlockingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are muted by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting + */ + async userMutingUsers(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/muting', options, { fullResponse: true, params }); + return new user_paginator_v2_1.UserMutingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Lists */ + /** + * Returns the details of a specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + */ + list(id, options = {}) { + return this.get('lists/:id', options, { params: { id } }); + } + /** + * Returns all Lists owned by the specified user. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists + */ + async listsOwned(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/owned_lists', options, { fullResponse: true, params }); + return new paginators_1.UserOwnedListsV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns all Lists a specified user is a member of. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-users-id-list_memberships + */ + async listMemberships(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/list_memberships', options, { fullResponse: true, params }); + return new paginators_1.UserListMembershipsV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns all Lists a specified user follows. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-users-id-followed_lists + */ + async listFollowed(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/followed_lists', options, { fullResponse: true, params }); + return new paginators_1.UserListFollowedV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of Tweets from the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-tweets/api-reference/get-lists-id-tweets + */ + async listTweets(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/tweets', options, { fullResponse: true, params }); + return new paginators_1.TweetV2ListTweetsPaginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are members of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-lists-id-members + */ + async listMembers(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/members', options, { fullResponse: true, params }); + return new user_paginator_v2_1.UserListMembersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are followers of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-lists-id-followers + */ + async listFollowers(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/followers', options, { fullResponse: true, params }); + return new user_paginator_v2_1.UserListFollowersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Direct messages */ + /** + * Returns a list of Direct Messages for the authenticated user, both sent and received. + * Direct Message events are returned in reverse chronological order. + * Supports retrieving events from the previous 30 days. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_events + */ + async listDmEvents(options = {}) { + const initialRq = await this.get('dm_events', options, { fullResponse: true }); + return new dm_paginator_v2_1.FullDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + }); + } + /** + * Returns a list of Direct Messages (DM) events within a 1-1 conversation with the user specified in the participant_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + async listDmEventsWithParticipant(participantId, options = {}) { + const params = { participant_id: participantId }; + const initialRq = await this.get('dm_conversations/with/:participant_id/dm_events', options, { fullResponse: true, params }); + return new dm_paginator_v2_1.OneToOneDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of Direct Messages within a conversation specified in the dm_conversation_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + async listDmEventsOfConversation(dmConversationId, options = {}) { + const params = { dm_conversation_id: dmConversationId }; + const initialRq = await this.get('dm_conversations/:dm_conversation_id/dm_events', options, { fullResponse: true, params }); + return new dm_paginator_v2_1.ConversationDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Spaces */ + /** + * Get a single space by ID. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + space(spaceId, options = {}) { + return this.get('spaces/:id', options, { params: { id: spaceId } }); + } + /** + * Get spaces using their IDs. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaces(spaceIds, options = {}) { + return this.get('spaces', { ids: spaceIds, ...options }); + } + /** + * Get spaces using their creator user ID(s). (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spacesByCreators(creatorIds, options = {}) { + return this.get('spaces/by/creator_ids', { user_ids: creatorIds, ...options }); + } + /** + * Search through spaces using multiple params. (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search + */ + searchSpaces(options) { + return this.get('spaces/search', options); + } + /** + * Returns a list of user who purchased a ticket to the requested Space. + * You must authenticate the request using the Access Token of the creator of the requested Space. + * + * **OAuth 2.0 Access Token required** + * + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-buyers + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaceBuyers(spaceId, options = {}) { + return this.get('spaces/:id/buyers', options, { params: { id: spaceId } }); + } + /** + * Returns Tweets shared in the requested Spaces. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-tweets + * + * OAuth2 scope: `users.read`, `tweet.read`, `space.read` + */ + spaceTweets(spaceId, options = {}) { + return this.get('spaces/:id/tweets', options, { params: { id: spaceId } }); + } + searchStream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/search/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload, autoConnect }); + } + /** + * Return a list of rules currently active on the streaming endpoint, either as a list or individually. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules + */ + streamRules(options = {}) { + return this.get('tweets/search/stream/rules', options); + } + updateStreamRules(options, query = {}) { + return this.post('tweets/search/stream/rules', options, { query }); + } + sampleStream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/sample/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload, autoConnect }); + } + sample10Stream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/sample10/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload, autoConnect }); + } + /* Batch compliance */ + /** + * Returns a list of recent compliance jobs. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs + */ + complianceJobs(options) { + return this.get('compliance/jobs', options); + } + /** + * Get a single compliance job with the specified ID. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs-id + */ + complianceJob(jobId) { + return this.get('compliance/jobs/:id', undefined, { params: { id: jobId } }); + } + /** + * Creates a new compliance job for Tweet IDs or user IDs, send your file, await result and parse it into an array. + * You can run one batch job at a time. Returns the created job, but **not the job result!**. + * + * You can obtain the result (**after job is completed**) with `.complianceJobResult`. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + async sendComplianceJob(jobParams) { + const job = await this.post('compliance/jobs', { type: jobParams.type, name: jobParams.name }); + // Send the IDs + const rawIdsBody = jobParams.ids instanceof Buffer ? jobParams.ids : Buffer.from(jobParams.ids.join('\n')); + // Upload the IDs + await this.put(job.data.upload_url, rawIdsBody, { + forceBodyMode: 'raw', + enableAuth: false, + headers: { 'Content-Type': 'text/plain' }, + prefix: '', + }); + return job; + } + /** + * Get the result of a running or completed job, obtained through `.complianceJob`, `.complianceJobs` or `.sendComplianceJob`. + * If job is still running (`in_progress`), it will await until job is completed. **This could be quite long!** + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + async complianceJobResult(job) { + let runningJob = job; + while (runningJob.status !== 'complete') { + if (runningJob.status === 'expired' || runningJob.status === 'failed') { + throw new Error('Job failed to be completed.'); + } + await new Promise(resolve => setTimeout(resolve, 3500)); + runningJob = (await this.complianceJob(job.id)).data; + } + // Download and parse result + const result = await this.get(job.download_url, undefined, { + enableAuth: false, + prefix: '', + }); + return result + .trim() + .split('\n') + .filter(line => line) + .map(line => JSON.parse(line)); + } +} +exports.default = TwitterApiv2ReadOnly; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.d.ts new file mode 100644 index 0000000..41c8dbb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.d.ts @@ -0,0 +1,204 @@ +import TwitterApiv2ReadOnly from './client.v2.read'; +import type { ListCreateV2Params, ListCreateV2Result, ListDeleteV2Result, ListFollowV2Result, ListMemberV2Result, ListPinV2Result, ListUpdateV2Params, ListUpdateV2Result, TweetV2DeleteTweetResult, SendTweetV2Params, TweetV2HideReplyResult, TweetV2LikeResult, TweetV2PostTweetResult, TweetV2RetweetResult, UserV2BlockResult, UserV2FollowResult, UserV2MuteResult, UserV2UnfollowResult, TweetV2BookmarkResult } from '../types'; +import TwitterApiv2LabsReadWrite from '../v2-labs/client.v2.labs.write'; +import { CreateDMConversationParams, PostDMInConversationParams, PostDMInConversationResult } from '../types/v2/dm.v2.types'; +/** + * Base Twitter v2 client with read/write rights. + */ +export default class TwitterApiv2ReadWrite extends TwitterApiv2ReadOnly { + protected _prefix: string; + protected _labs?: TwitterApiv2LabsReadWrite; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv2ReadOnly; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2LabsReadWrite; + /** + * Hides or unhides a reply to a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/hide-replies/api-reference/put-tweets-id-hidden + */ + hideReply(tweetId: string, makeHidden: boolean): Promise; + /** + * Causes the user ID identified in the path parameter to Like the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-user_id-likes + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + like(loggedUserId: string, targetTweetId: string): Promise; + /** + * Allows a user or authenticated user ID to unlike a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not liking the Tweet or have already unliked the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unlike(loggedUserId: string, targetTweetId: string): Promise; + /** + * Causes the user ID identified in the path parameter to Retweet the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + retweet(loggedUserId: string, targetTweetId: string): Promise; + /** + * Allows a user or authenticated user ID to remove the Retweet of a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not Retweeting the Tweet or have already removed the Retweet of. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unretweet(loggedUserId: string, targetTweetId: string): Promise; + /** + * Creates a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + tweet(status: string, payload?: Partial): Promise; + tweet(payload: SendTweetV2Params): Promise; + /** + * Reply to a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + reply(status: string, toTweetId: string, payload?: Partial): Promise; + /** + * Quote an existing Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + quote(status: string, quotedTweetId: string, payload?: Partial): Promise; + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + tweetThread(tweets: (SendTweetV2Params | string)[]): Promise; + /** + * Allows a user or authenticated user ID to delete a Tweet + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + */ + deleteTweet(tweetId: string): Promise; + /** + * Causes the user ID of an authenticated user identified in the path parameter to Bookmark the target Tweet provided in the request body. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + bookmark(tweetId: string): Promise; + /** + * Allows a user or authenticated user ID to remove a Bookmark of a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + deleteBookmark(tweetId: string): Promise; + /** + * Allows a user ID to follow another user. + * If the target user does not have public Tweets, this endpoint will send a follow request. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/post-users-source_user_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + follow(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows a user ID to unfollow another user. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unfollow(loggedUserId: string, targetUserId: string): Promise; + /** + * Causes the user (in the path) to block the target user. + * The user (in the path) must match the user context authorizing the request. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID; you can obtain it through v1.1 API. + */ + block(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows a user or authenticated user ID to unblock another user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unblock(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows an authenticated user ID to mute the target user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + mute(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows an authenticated user ID to unmute the target user. + * The request succeeds with no action when the user sends a request to a user they're not muting or have already unmuted. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unmute(loggedUserId: string, targetUserId: string): Promise; + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists + */ + createList(options: ListCreateV2Params): Promise; + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/put-lists-id + */ + updateList(listId: string, options?: ListUpdateV2Params): Promise; + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id + */ + removeList(listId: string): Promise; + /** + * Adds a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists-id-members + */ + addListMember(listId: string, userId: string): Promise; + /** + * Remember a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id-members-user_id + */ + removeListMember(listId: string, userId: string): Promise; + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-followed-lists + */ + subscribeToList(loggedUserId: string, listId: string): Promise; + /** + * Unsubscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-followed-lists-list_id + */ + unsubscribeOfList(loggedUserId: string, listId: string): Promise; + /** + * Enables the authenticated user to pin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-pinned-lists + */ + pinList(loggedUserId: string, listId: string): Promise; + /** + * Enables the authenticated user to unpin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-pinned-lists-list_id + */ + unpinList(loggedUserId: string, listId: string): Promise; + /** + * Creates a Direct Message on behalf of an authenticated user, and adds it to the specified conversation. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-dm_conversation_id-messages + */ + sendDmInConversation(conversationId: string, message: PostDMInConversationParams): Promise; + /** + * Creates a one-to-one Direct Message and adds it to the one-to-one conversation. + * This method either creates a new one-to-one conversation or retrieves the current conversation and adds the Direct Message to it. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-with-participant_id-messages + */ + sendDmToParticipant(participantId: string, message: PostDMInConversationParams): Promise; + /** + * Creates a new group conversation and adds a Direct Message to it on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations + */ + createDmConversation(options: CreateDMConversationParams): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.js b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.js new file mode 100644 index 0000000..0d3214e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/client.v2.write.js @@ -0,0 +1,319 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const globals_1 = require("../globals"); +const client_v2_read_1 = __importDefault(require("./client.v2.read")); +const client_v2_labs_write_1 = __importDefault(require("../v2-labs/client.v2.labs.write")); +/** + * Base Twitter v2 client with read/write rights. + */ +class TwitterApiv2ReadWrite extends client_v2_read_1.default { + constructor() { + super(...arguments); + this._prefix = globals_1.API_V2_PREFIX; + } + /* Sub-clients */ + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new client_v2_labs_write_1.default(this); + } + /* Tweets */ + /** + * Hides or unhides a reply to a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/hide-replies/api-reference/put-tweets-id-hidden + */ + hideReply(tweetId, makeHidden) { + return this.put('tweets/:id/hidden', { hidden: makeHidden }, { params: { id: tweetId } }); + } + /** + * Causes the user ID identified in the path parameter to Like the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-user_id-likes + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + like(loggedUserId, targetTweetId) { + return this.post('users/:id/likes', { tweet_id: targetTweetId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to unlike a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not liking the Tweet or have already unliked the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unlike(loggedUserId, targetTweetId) { + return this.delete('users/:id/likes/:tweet_id', undefined, { + params: { id: loggedUserId, tweet_id: targetTweetId }, + }); + } + /** + * Causes the user ID identified in the path parameter to Retweet the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + retweet(loggedUserId, targetTweetId) { + return this.post('users/:id/retweets', { tweet_id: targetTweetId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to remove the Retweet of a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not Retweeting the Tweet or have already removed the Retweet of. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unretweet(loggedUserId, targetTweetId) { + return this.delete('users/:id/retweets/:tweet_id', undefined, { + params: { id: loggedUserId, tweet_id: targetTweetId }, + }); + } + tweet(status, payload = {}) { + if (typeof status === 'object') { + payload = status; + } + else { + payload = { text: status, ...payload }; + } + return this.post('tweets', payload); + } + /** + * Reply to a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + reply(status, toTweetId, payload = {}) { + var _a; + const reply = { in_reply_to_tweet_id: toTweetId, ...(_a = payload.reply) !== null && _a !== void 0 ? _a : {} }; + return this.post('tweets', { text: status, ...payload, reply }); + } + /** + * Quote an existing Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + quote(status, quotedTweetId, payload = {}) { + return this.tweet(status, { ...payload, quote_tweet_id: quotedTweetId }); + } + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + async tweetThread(tweets) { + var _a, _b; + const postedTweets = []; + for (const tweet of tweets) { + // Retrieve the last sent tweet + const lastTweet = postedTweets.length ? postedTweets[postedTweets.length - 1] : null; + // Build the tweet query params + const queryParams = { ...(typeof tweet === 'string' ? ({ text: tweet }) : tweet) }; + // Reply to an existing tweet if needed + const inReplyToId = lastTweet ? lastTweet.data.id : (_a = queryParams.reply) === null || _a === void 0 ? void 0 : _a.in_reply_to_tweet_id; + const status = (_b = queryParams.text) !== null && _b !== void 0 ? _b : ''; + if (inReplyToId) { + postedTweets.push(await this.reply(status, inReplyToId, queryParams)); + } + else { + postedTweets.push(await this.tweet(status, queryParams)); + } + } + return postedTweets; + } + /** + * Allows a user or authenticated user ID to delete a Tweet + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + */ + deleteTweet(tweetId) { + return this.delete('tweets/:id', undefined, { + params: { + id: tweetId, + }, + }); + } + /* Bookmarks */ + /** + * Causes the user ID of an authenticated user identified in the path parameter to Bookmark the target Tweet provided in the request body. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + async bookmark(tweetId) { + const user = await this.getCurrentUserV2Object(); + return this.post('users/:id/bookmarks', { tweet_id: tweetId }, { params: { id: user.data.id } }); + } + /** + * Allows a user or authenticated user ID to remove a Bookmark of a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + async deleteBookmark(tweetId) { + const user = await this.getCurrentUserV2Object(); + return this.delete('users/:id/bookmarks/:tweet_id', undefined, { params: { id: user.data.id, tweet_id: tweetId } }); + } + /* Users */ + /** + * Allows a user ID to follow another user. + * If the target user does not have public Tweets, this endpoint will send a follow request. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/post-users-source_user_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + follow(loggedUserId, targetUserId) { + return this.post('users/:id/following', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user ID to unfollow another user. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unfollow(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/following/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /** + * Causes the user (in the path) to block the target user. + * The user (in the path) must match the user context authorizing the request. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID; you can obtain it through v1.1 API. + */ + block(loggedUserId, targetUserId) { + return this.post('users/:id/blocking', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to unblock another user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unblock(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/blocking/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /** + * Allows an authenticated user ID to mute the target user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + mute(loggedUserId, targetUserId) { + return this.post('users/:id/muting', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows an authenticated user ID to unmute the target user. + * The request succeeds with no action when the user sends a request to a user they're not muting or have already unmuted. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unmute(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/muting/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /* Lists */ + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists + */ + createList(options) { + return this.post('lists', options); + } + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/put-lists-id + */ + updateList(listId, options = {}) { + return this.put('lists/:id', options, { params: { id: listId } }); + } + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id + */ + removeList(listId) { + return this.delete('lists/:id', undefined, { params: { id: listId } }); + } + /** + * Adds a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists-id-members + */ + addListMember(listId, userId) { + return this.post('lists/:id/members', { user_id: userId }, { params: { id: listId } }); + } + /** + * Remember a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id-members-user_id + */ + removeListMember(listId, userId) { + return this.delete('lists/:id/members/:user_id', undefined, { params: { id: listId, user_id: userId } }); + } + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-followed-lists + */ + subscribeToList(loggedUserId, listId) { + return this.post('users/:id/followed_lists', { list_id: listId }, { params: { id: loggedUserId } }); + } + /** + * Unsubscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-followed-lists-list_id + */ + unsubscribeOfList(loggedUserId, listId) { + return this.delete('users/:id/followed_lists/:list_id', undefined, { params: { id: loggedUserId, list_id: listId } }); + } + /** + * Enables the authenticated user to pin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-pinned-lists + */ + pinList(loggedUserId, listId) { + return this.post('users/:id/pinned_lists', { list_id: listId }, { params: { id: loggedUserId } }); + } + /** + * Enables the authenticated user to unpin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-pinned-lists-list_id + */ + unpinList(loggedUserId, listId) { + return this.delete('users/:id/pinned_lists/:list_id', undefined, { params: { id: loggedUserId, list_id: listId } }); + } + /* Direct messages */ + /** + * Creates a Direct Message on behalf of an authenticated user, and adds it to the specified conversation. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-dm_conversation_id-messages + */ + sendDmInConversation(conversationId, message) { + return this.post('dm_conversations/:dm_conversation_id/messages', message, { params: { dm_conversation_id: conversationId } }); + } + /** + * Creates a one-to-one Direct Message and adds it to the one-to-one conversation. + * This method either creates a new one-to-one conversation or retrieves the current conversation and adds the Direct Message to it. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-with-participant_id-messages + */ + sendDmToParticipant(participantId, message) { + return this.post('dm_conversations/with/:participant_id/messages', message, { params: { participant_id: participantId } }); + } + /** + * Creates a new group conversation and adds a Direct Message to it on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations + */ + createDmConversation(options) { + return this.post('dm_conversations', options); + } +} +exports.default = TwitterApiv2ReadWrite; diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.d.ts b/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.d.ts new file mode 100644 index 0000000..639f9eb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.d.ts @@ -0,0 +1,82 @@ +import type { ApiV2Includes, ListV2, SpaceV2, TweetV2, UserV2 } from '../types'; +export declare type TTwitterV2IncludesResult = { + includes?: ApiV2Includes; +}; +/** + * Provide helpers for `.includes` of a v2 API result. + * Needed expansions for a method to work are specified (*`like this`*). + */ +export declare class TwitterV2IncludesHelper implements ApiV2Includes { + protected result: TTwitterV2IncludesResult; + constructor(result: TTwitterV2IncludesResult); + get tweets(): TweetV2[]; + static tweets(result: TTwitterV2IncludesResult): TweetV2[]; + tweetById(id: string): TweetV2 | undefined; + static tweetById(result: TTwitterV2IncludesResult, id: string): TweetV2 | undefined; + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + retweet(tweet: TweetV2): TweetV2 | undefined; + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + static retweet(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + quote(tweet: TweetV2): TweetV2 | undefined; + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + static quote(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + repliedTo(tweet: TweetV2): TweetV2 | undefined; + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + static repliedTo(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + author(tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + static author(result: TTwitterV2IncludesResult, tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + repliedToAuthor(tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + static repliedToAuthor(result: TTwitterV2IncludesResult, tweet: TweetV2): UserV2 | undefined; + get users(): UserV2[]; + static users(result: TTwitterV2IncludesResult): UserV2[]; + userById(id: string): UserV2 | undefined; + static userById(result: TTwitterV2IncludesResult, id: string): UserV2 | undefined; + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + pinnedTweet(user: UserV2): TweetV2 | undefined; + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + static pinnedTweet(result: TTwitterV2IncludesResult, user: UserV2): TweetV2 | undefined; + get media(): import("../types").MediaObjectV2[]; + static media(result: TTwitterV2IncludesResult): import("../types").MediaObjectV2[]; + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + medias(tweet: TweetV2): import("../types").MediaObjectV2[]; + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + static medias(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").MediaObjectV2[]; + get polls(): import("../types").PollV2[]; + static polls(result: TTwitterV2IncludesResult): import("../types").PollV2[]; + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + poll(tweet: TweetV2): import("../types").PollV2 | undefined; + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + static poll(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").PollV2 | undefined; + get places(): import("../types").PlaceV2[]; + static places(result: TTwitterV2IncludesResult): import("../types").PlaceV2[]; + /** Place associated with the given tweet (*`geo.place_id`*) */ + place(tweet: TweetV2): import("../types").PlaceV2 | undefined; + /** Place associated with the given tweet (*`geo.place_id`*) */ + static place(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").PlaceV2 | undefined; + /** List owner of the given list (*`owner_id`*) */ + listOwner(list: ListV2): UserV2 | undefined; + /** List owner of the given list (*`owner_id`*) */ + static listOwner(result: TTwitterV2IncludesResult, list: ListV2): UserV2 | undefined; + /** Creator of the given space (*`creator_id`*) */ + spaceCreator(space: SpaceV2): UserV2 | undefined; + /** Creator of the given space (*`creator_id`*) */ + static spaceCreator(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2 | undefined; + /** Current hosts of the given space (*`host_ids`*) */ + spaceHosts(space: SpaceV2): UserV2[]; + /** Current hosts of the given space (*`host_ids`*) */ + static spaceHosts(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; + /** Current speakers of the given space (*`speaker_ids`*) */ + spaceSpeakers(space: SpaceV2): UserV2[]; + /** Current speakers of the given space (*`speaker_ids`*) */ + static spaceSpeakers(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; + /** Current invited users of the given space (*`invited_user_ids`*) */ + spaceInvitedUsers(space: SpaceV2): UserV2[]; + /** Current invited users of the given space (*`invited_user_ids`*) */ + static spaceInvitedUsers(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; +} diff --git a/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.js b/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.js new file mode 100644 index 0000000..e4690cd --- /dev/null +++ b/node_modules/twitter-api-v2/dist/cjs/v2/includes.v2.helper.js @@ -0,0 +1,211 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TwitterV2IncludesHelper = void 0; +/** + * Provide helpers for `.includes` of a v2 API result. + * Needed expansions for a method to work are specified (*`like this`*). + */ +class TwitterV2IncludesHelper { + constructor(result) { + this.result = result; + } + /* Tweets */ + get tweets() { + return TwitterV2IncludesHelper.tweets(this.result); + } + static tweets(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.tweets) !== null && _b !== void 0 ? _b : []; + } + tweetById(id) { + return TwitterV2IncludesHelper.tweetById(this.result, id); + } + static tweetById(result, id) { + return this.tweets(result).find(tweet => tweet.id === id); + } + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + retweet(tweet) { + return TwitterV2IncludesHelper.retweet(this.result, tweet); + } + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + static retweet(result, tweet) { + var _a; + const retweetIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'retweeted') + .map(ref => ref.id); + return this.tweets(result).find(t => retweetIds.includes(t.id)); + } + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + quote(tweet) { + return TwitterV2IncludesHelper.quote(this.result, tweet); + } + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + static quote(result, tweet) { + var _a; + const quoteIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'quoted') + .map(ref => ref.id); + return this.tweets(result).find(t => quoteIds.includes(t.id)); + } + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + repliedTo(tweet) { + return TwitterV2IncludesHelper.repliedTo(this.result, tweet); + } + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + static repliedTo(result, tweet) { + var _a; + const repliesIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'replied_to') + .map(ref => ref.id); + return this.tweets(result).find(t => repliesIds.includes(t.id)); + } + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + author(tweet) { + return TwitterV2IncludesHelper.author(this.result, tweet); + } + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + static author(result, tweet) { + const authorId = tweet.author_id; + return authorId ? this.users(result).find(u => u.id === authorId) : undefined; + } + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + repliedToAuthor(tweet) { + return TwitterV2IncludesHelper.repliedToAuthor(this.result, tweet); + } + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + static repliedToAuthor(result, tweet) { + const inReplyUserId = tweet.in_reply_to_user_id; + return inReplyUserId ? this.users(result).find(u => u.id === inReplyUserId) : undefined; + } + /* Users */ + get users() { + return TwitterV2IncludesHelper.users(this.result); + } + static users(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.users) !== null && _b !== void 0 ? _b : []; + } + userById(id) { + return TwitterV2IncludesHelper.userById(this.result, id); + } + static userById(result, id) { + return this.users(result).find(u => u.id === id); + } + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + pinnedTweet(user) { + return TwitterV2IncludesHelper.pinnedTweet(this.result, user); + } + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + static pinnedTweet(result, user) { + return user.pinned_tweet_id ? this.tweets(result).find(t => t.id === user.pinned_tweet_id) : undefined; + } + /* Medias */ + get media() { + return TwitterV2IncludesHelper.media(this.result); + } + static media(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.media) !== null && _b !== void 0 ? _b : []; + } + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + medias(tweet) { + return TwitterV2IncludesHelper.medias(this.result, tweet); + } + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + static medias(result, tweet) { + var _a, _b; + const keys = (_b = (_a = tweet.attachments) === null || _a === void 0 ? void 0 : _a.media_keys) !== null && _b !== void 0 ? _b : []; + return this.media(result).filter(m => keys.includes(m.media_key)); + } + /* Polls */ + get polls() { + return TwitterV2IncludesHelper.polls(this.result); + } + static polls(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.polls) !== null && _b !== void 0 ? _b : []; + } + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + poll(tweet) { + return TwitterV2IncludesHelper.poll(this.result, tweet); + } + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + static poll(result, tweet) { + var _a, _b; + const pollIds = (_b = (_a = tweet.attachments) === null || _a === void 0 ? void 0 : _a.poll_ids) !== null && _b !== void 0 ? _b : []; + if (pollIds.length) { + const pollId = pollIds[0]; + return this.polls(result).find(p => p.id === pollId); + } + return undefined; + } + /* Places */ + get places() { + return TwitterV2IncludesHelper.places(this.result); + } + static places(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.places) !== null && _b !== void 0 ? _b : []; + } + /** Place associated with the given tweet (*`geo.place_id`*) */ + place(tweet) { + return TwitterV2IncludesHelper.place(this.result, tweet); + } + /** Place associated with the given tweet (*`geo.place_id`*) */ + static place(result, tweet) { + var _a; + const placeId = (_a = tweet.geo) === null || _a === void 0 ? void 0 : _a.place_id; + return placeId ? this.places(result).find(p => p.id === placeId) : undefined; + } + /* Lists */ + /** List owner of the given list (*`owner_id`*) */ + listOwner(list) { + return TwitterV2IncludesHelper.listOwner(this.result, list); + } + /** List owner of the given list (*`owner_id`*) */ + static listOwner(result, list) { + const creatorId = list.owner_id; + return creatorId ? this.users(result).find(p => p.id === creatorId) : undefined; + } + /* Spaces */ + /** Creator of the given space (*`creator_id`*) */ + spaceCreator(space) { + return TwitterV2IncludesHelper.spaceCreator(this.result, space); + } + /** Creator of the given space (*`creator_id`*) */ + static spaceCreator(result, space) { + const creatorId = space.creator_id; + return creatorId ? this.users(result).find(p => p.id === creatorId) : undefined; + } + /** Current hosts of the given space (*`host_ids`*) */ + spaceHosts(space) { + return TwitterV2IncludesHelper.spaceHosts(this.result, space); + } + /** Current hosts of the given space (*`host_ids`*) */ + static spaceHosts(result, space) { + var _a; + const hostIds = (_a = space.host_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => hostIds.includes(u.id)); + } + /** Current speakers of the given space (*`speaker_ids`*) */ + spaceSpeakers(space) { + return TwitterV2IncludesHelper.spaceSpeakers(this.result, space); + } + /** Current speakers of the given space (*`speaker_ids`*) */ + static spaceSpeakers(result, space) { + var _a; + const speakerIds = (_a = space.speaker_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => speakerIds.includes(u.id)); + } + /** Current invited users of the given space (*`invited_user_ids`*) */ + spaceInvitedUsers(space) { + return TwitterV2IncludesHelper.spaceInvitedUsers(this.result, space); + } + /** Current invited users of the given space (*`invited_user_ids`*) */ + static spaceInvitedUsers(result, space) { + var _a; + const invitedUserIds = (_a = space.invited_user_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => invitedUserIds.includes(u.id)); + } +} +exports.TwitterV2IncludesHelper = TwitterV2IncludesHelper; diff --git a/node_modules/twitter-api-v2/dist/esm/client-mixins/form-data.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/form-data.helper.d.ts new file mode 100644 index 0000000..78af26c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/form-data.helper.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/form-data.helper.js new file mode 100644 index 0000000..5c72868 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/form-data.helper.js @@ -0,0 +1,79 @@ +import { arrayWrap } from '../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. +export 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 + ': ' + 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); + } +} +FormDataHelper.LINE_BREAK = '\r\n'; +FormDataHelper.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; diff --git a/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth1.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth1.helper.d.ts new file mode 100644 index 0000000..b897933 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/oauth1.helper.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth1.helper.js new file mode 100644 index 0000000..7ffd7b7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth1.helper.js @@ -0,0 +1,160 @@ +import * as crypto from 'crypto'; +export 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]; + } +} +export 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/esm/client-mixins/oauth2.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth2.helper.d.ts new file mode 100644 index 0000000..7b8c886 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/oauth2.helper.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth2.helper.js new file mode 100644 index 0000000..4f94b0a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/oauth2.helper.js @@ -0,0 +1,27 @@ +import * as crypto from 'crypto'; +export 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, '_'); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/client-mixins/request-handler.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-handler.helper.d.ts new file mode 100644 index 0000000..34c76f6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/request-handler.helper.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-handler.helper.js new file mode 100644 index 0000000..241c3ef --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-handler.helper.js @@ -0,0 +1,361 @@ +import { request } from 'https'; +import { TwitterApiV2Settings } from '../settings'; +import TweetStream from '../stream/TweetStream'; +import { ApiPartialResponseError, ApiRequestError, ApiResponseError } from '../types'; +import * as zlib from 'zlib'; +export 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 (TwitterApiV2Settings.debug) { + TwitterApiV2Settings.logger.log('Request error:', error); + } + return new 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 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 (TwitterApiV2Settings.debug) { + TwitterApiV2Settings.logger.log(`Request failed with code ${code}, data:`, data); + 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 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 (TwitterApiV2Settings.debug) { + TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${this.res.statusCode}`); + 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 (TwitterApiV2Settings.debug) { + 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; + TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options); + if (url.search) { + TwitterApiV2Settings.logger.log('Request parameters:', [...url.searchParams.entries()].map(([key, value]) => `${key}: ${value}`)); + } + if (this.requestData.body) { + 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 (TwitterApiV2Settings.debug) { + this.debugRequest(); + } + this.req = 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(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(); + }); + } +} +export default RequestHandlerHelper; diff --git a/node_modules/twitter-api-v2/dist/esm/client-mixins/request-maker.mixin.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-maker.mixin.d.ts new file mode 100644 index 0000000..f4160c4 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/request-maker.mixin.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-maker.mixin.js new file mode 100644 index 0000000..36e7e43 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-maker.mixin.js @@ -0,0 +1,316 @@ +import { TwitterApiPluginResponseOverride } from '../types'; +import TweetStream from '../stream/TweetStream'; +import { applyResponseHooks, hasRequestErrorPlugins } from '../plugins/helpers'; +import { trimUndefinedProperties } from '../helpers'; +import OAuth1Helper from './oauth1.helper'; +import RequestHandlerHelper from './request-handler.helper'; +import RequestParamHelpers from './request-param.helper'; +import { OAuth2Helper } from './oauth2.helper'; +export 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) { + RequestParamHelpers.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 RequestHandlerHelper({ + 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 (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) { + RequestParamHelpers.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(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 OAuth1Helper({ + 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 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 ' + OAuth2Helper.getAuthHeader(this.clientId, this.clientSecret); + } + else if (this.consumerSecret && this._oauth) { + // Merge query and body + const data = bodyInSignature ? RequestParamHelpers.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) { + RequestParamHelpers.applyRequestParametersToUrl(url, params); + } + // Build a URL without anything in QS, and QSP in query + const query = RequestParamHelpers.formatQueryToString(rawQuery); + RequestParamHelpers.moveUrlQueryParamsIntoObject(url, query); + // Delete undefined parameters + if (!(rawBody instanceof Buffer)) { + trimUndefinedProperties(rawBody); + } + // OAuth signature should not include parameters when using multipart. + const bodyType = forceBodyMode !== null && forceBodyMode !== void 0 ? forceBodyMode : RequestParamHelpers.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 = RequestParamHelpers.constructBodyParams(rawBody, headers, bodyType) || undefined; + } + RequestParamHelpers.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(applyResponseHooks.bind(this, requestParams, computedParams, requestOptions)); + } +} +ClientRequestMaker.BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']); diff --git a/node_modules/twitter-api-v2/dist/esm/client-mixins/request-param.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-param.helper.d.ts new file mode 100644 index 0000000..7c220e0 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client-mixins/request-param.helper.js b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-param.helper.js new file mode 100644 index 0000000..37ed75e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client-mixins/request-param.helper.js @@ -0,0 +1,144 @@ +import { FormDataHelper } from './form-data.helper'; +import OAuth1Helper from './oauth1.helper'; +/* Helpers functions that are specific to this class but do not depends on instance */ +export 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 ? '&' : '?') + `${OAuth1Helper.percentEncode(key)}=${OAuth1Helper.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 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; + } +} +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', +]); +export default RequestParamHelpers; diff --git a/node_modules/twitter-api-v2/dist/esm/client.base.d.ts b/node_modules/twitter-api-v2/dist/esm/client.base.d.ts new file mode 100644 index 0000000..2bc89c2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client.base.js b/node_modules/twitter-api-v2/dist/esm/client.base.js new file mode 100644 index 0000000..dcc32ad --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client.base.js @@ -0,0 +1,176 @@ +import { ClientRequestMaker } from './client-mixins/request-maker.mixin'; +import { sharedPromise } from './helpers'; +import { API_V1_1_PREFIX, API_V2_PREFIX } from './globals'; +/** + * Base class for Twitter instances + */ +export default class TwitterApiBase { + constructor(token, settings = {}) { + this._currentUser = null; + this._currentUserV2 = null; + if (token instanceof TwitterApiBase) { + this._requestMaker = token._requestMaker; + } + else { + this._requestMaker = new 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 = sharedPromise(() => this.get('account/verify_credentials.json', { tweet_mode: 'extended' }, { prefix: 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 = sharedPromise(() => this.get('users/me', undefined, { prefix: 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, + }); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/client.subclient.d.ts b/node_modules/twitter-api-v2/dist/esm/client.subclient.d.ts new file mode 100644 index 0000000..e468a03 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client.subclient.js b/node_modules/twitter-api-v2/dist/esm/client.subclient.js new file mode 100644 index 0000000..46bede8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client.subclient.js @@ -0,0 +1,12 @@ +import TwitterApiBase from './client.base'; +/** + * Base subclient for every v1 and v2 client. + */ +export default class TwitterApiSubClient extends TwitterApiBase { + constructor(instance) { + if (!(instance instanceof TwitterApiBase)) { + throw new Error('You must instance SubTwitterApi instance from existing TwitterApi instance.'); + } + super(instance); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/client/index.d.ts b/node_modules/twitter-api-v2/dist/esm/client/index.d.ts new file mode 100644 index 0000000..5d7285b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client/index.js b/node_modules/twitter-api-v2/dist/esm/client/index.js new file mode 100644 index 0000000..d20ba51 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client/index.js @@ -0,0 +1,61 @@ +import TwitterApiv1 from '../v1/client.v1'; +import TwitterApiv2 from '../v2/client.v2'; +import TwitterApiReadWrite from './readwrite'; +// "Real" exported client for usage of TwitterApi. +/** + * Twitter v1.1 and v2 API client. + */ +export class TwitterApi extends TwitterApiReadWrite { + /* Direct access to subclients */ + get v1() { + if (this._v1) + return this._v1; + return this._v1 = new TwitterApiv1(this); + } + get v2() { + if (this._v2) + return this._v2; + return this._v2 = new TwitterApiv2(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; + } + } +} +export { default as TwitterApiReadWrite } from './readwrite'; +export { default as TwitterApiReadOnly } from './readonly'; +export default TwitterApi; diff --git a/node_modules/twitter-api-v2/dist/esm/client/readonly.d.ts b/node_modules/twitter-api-v2/dist/esm/client/readonly.d.ts new file mode 100644 index 0000000..c486627 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client/readonly.js b/node_modules/twitter-api-v2/dist/esm/client/readonly.js new file mode 100644 index 0000000..a31fa46 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client/readonly.js @@ -0,0 +1,299 @@ +import TwitterApi from '.'; +import TwitterApiBase from '../client.base'; +import TwitterApiv1ReadOnly from '../v1/client.v1.read'; +import TwitterApiv2ReadOnly from '../v2/client.v2.read'; +import { OAuth2Helper } from '../client-mixins/oauth2.helper'; +import RequestParamHelpers from '../client-mixins/request-param.helper'; +/** + * Twitter v1.1 and v2 API client. + */ +export default class TwitterApiReadOnly extends TwitterApiBase { + /* Direct access to subclients */ + get v1() { + if (this._v1) + return this._v1; + return this._v1 = new TwitterApiv1ReadOnly(this); + } + get v2() { + if (this._v2) + return this._v2; + return this._v2 = new TwitterApiv2ReadOnly(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 TwitterApi({ + 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 TwitterApi({ 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 TwitterApi(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 : OAuth2Helper.generateRandomString(32); + const codeVerifier = OAuth2Helper.getCodeVerifier(); + const codeChallenge = 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, + }; + RequestParamHelpers.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 TwitterApi(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, + }; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/client/readwrite.d.ts b/node_modules/twitter-api-v2/dist/esm/client/readwrite.d.ts new file mode 100644 index 0000000..c2e35b8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/client/readwrite.js b/node_modules/twitter-api-v2/dist/esm/client/readwrite.js new file mode 100644 index 0000000..fef8248 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/client/readwrite.js @@ -0,0 +1,25 @@ +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 { + /* Direct access to subclients */ + get v1() { + if (this._v1) + return this._v1; + return this._v1 = new TwitterApiv1ReadWrite(this); + } + get v2() { + if (this._v2) + return this._v2; + return this._v2 = new TwitterApiv2ReadWrite(this); + } + /** + * Get a client with read only rights. + */ + get readOnly() { + return this; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/globals.d.ts b/node_modules/twitter-api-v2/dist/esm/globals.d.ts new file mode 100644 index 0000000..dcb64a6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/globals.js b/node_modules/twitter-api-v2/dist/esm/globals.js new file mode 100644 index 0000000..1497d54 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/globals.js @@ -0,0 +1,5 @@ +export const API_V2_PREFIX = 'https://api.twitter.com/2/'; +export const API_V2_LABS_PREFIX = 'https://api.twitter.com/labs/2/'; +export const API_V1_1_PREFIX = 'https://api.twitter.com/1.1/'; +export const API_V1_1_UPLOAD_PREFIX = 'https://upload.twitter.com/1.1/'; +export const API_V1_1_STREAM_PREFIX = 'https://stream.twitter.com/1.1/'; diff --git a/node_modules/twitter-api-v2/dist/esm/helpers.d.ts b/node_modules/twitter-api-v2/dist/esm/helpers.d.ts new file mode 100644 index 0000000..bbc3fa9 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/helpers.js b/node_modules/twitter-api-v2/dist/esm/helpers.js new file mode 100644 index 0000000..6dc35ed --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/helpers.js @@ -0,0 +1,51 @@ +import { TwitterApiV2Settings } from './settings'; +export function sharedPromise(getter) { + const sharedPromise = { + value: undefined, + promise: getter().then(val => { + sharedPromise.value = val; + return val; + }), + }; + return sharedPromise; +} +export function arrayWrap(value) { + if (Array.isArray(value)) { + return value; + } + return [value]; +} +export function trimUndefinedProperties(object) { + // Delete undefined parameters + for (const parameter in object) { + if (object[parameter] === undefined) + delete object[parameter]; + } +} +export 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); +} +export function hasMultipleItems(item) { + if (Array.isArray(item) && item.length > 1) { + return true; + } + return item.toString().includes(','); +} +const deprecationWarningsCache = new Set(); +export function safeDeprecationWarning(message) { + if (typeof console === 'undefined' || !console.warn || !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); +} diff --git a/node_modules/twitter-api-v2/dist/esm/index.d.ts b/node_modules/twitter-api-v2/dist/esm/index.d.ts new file mode 100644 index 0000000..98a08f9 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/index.js b/node_modules/twitter-api-v2/dist/esm/index.js new file mode 100644 index 0000000..98a08f9 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/index.js @@ -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/esm/paginators/TwitterPaginator.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/TwitterPaginator.d.ts new file mode 100644 index 0000000..788d1bb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/TwitterPaginator.js b/node_modules/twitter-api-v2/dist/esm/paginators/TwitterPaginator.js new file mode 100644 index 0000000..623294d --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/TwitterPaginator.js @@ -0,0 +1,168 @@ +/** TwitterPaginator: able to get consume data from initial request, then fetch next data sequentially. */ +export 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; + } + } +} +/** PreviousableTwitterPaginator: a TwitterPaginator able to get consume data from both side, next and previous. */ +export 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; + } +} +export default TwitterPaginator; diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v1.d.ts new file mode 100644 index 0000000..085f9d8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/dm.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v1.js new file mode 100644 index 0000000..cf5083a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v1.js @@ -0,0 +1,50 @@ +import { CursoredV1Paginator } from './paginator.v1'; +export class DmEventsV1Paginator extends 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; + } +} +export class WelcomeDmV1Paginator extends 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; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v2.d.ts new file mode 100644 index 0000000..60db343 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/dm.paginator.v2.js b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v2.js new file mode 100644 index 0000000..06fc764 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v2.js @@ -0,0 +1,34 @@ +import { TimelineV2Paginator } from './v2.paginator'; +export class DMTimelineV2Paginator extends 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; + } +} +export class FullDMTimelineV2Paginator extends DMTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'dm_events'; + } +} +export class OneToOneDMTimelineV2Paginator extends DMTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'dm_conversations/with/:participant_id/dm_events'; + } +} +export class ConversationDMTimelineV2Paginator extends DMTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'dm_conversations/:dm_conversation_id/dm_events'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/followers.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/followers.paginator.v1.d.ts new file mode 100644 index 0000000..4451e6e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/followers.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/followers.paginator.v1.js new file mode 100644 index 0000000..738814a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/followers.paginator.v1.js @@ -0,0 +1,54 @@ +import { CursoredV1Paginator } from './paginator.v1'; +export class UserFollowerListV1Paginator extends 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; + } +} +export class UserFollowerIdsV1Paginator extends 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; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/friends.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/friends.paginator.v1.d.ts new file mode 100644 index 0000000..9a3e35e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/friends.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/friends.paginator.v1.js new file mode 100644 index 0000000..dbb0183 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/friends.paginator.v1.js @@ -0,0 +1,54 @@ +import { CursoredV1Paginator } from './paginator.v1'; +export class UserFriendListV1Paginator extends 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; + } +} +export class UserFollowersIdsV1Paginator extends 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; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/index.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/index.d.ts new file mode 100644 index 0000000..6e2bbb2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/index.js b/node_modules/twitter-api-v2/dist/esm/paginators/index.js new file mode 100644 index 0000000..6e2bbb2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/index.js @@ -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/esm/paginators/list.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v1.d.ts new file mode 100644 index 0000000..7ab6bd3 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/list.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v1.js new file mode 100644 index 0000000..01d80ff --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v1.js @@ -0,0 +1,75 @@ +import { CursoredV1Paginator } from './paginator.v1'; +class ListListsV1Paginator extends 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; + } +} +export class ListMembershipsV1Paginator extends ListListsV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/memberships.json'; + } +} +export class ListOwnershipsV1Paginator extends ListListsV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/ownerships.json'; + } +} +export class ListSubscriptionsV1Paginator extends ListListsV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/subscriptions.json'; + } +} +class ListUsersV1Paginator extends 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; + } +} +export class ListMembersV1Paginator extends ListUsersV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/members.json'; + } +} +export class ListSubscribersV1Paginator extends ListUsersV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/subscribers.json'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v2.d.ts new file mode 100644 index 0000000..06ccf00 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/list.paginator.v2.js b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v2.js new file mode 100644 index 0000000..ea46eb4 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/list.paginator.v2.js @@ -0,0 +1,34 @@ +import { TimelineV2Paginator } from './v2.paginator'; +class ListTimelineV2Paginator extends 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; + } +} +export class UserOwnedListsV2Paginator extends ListTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/owned_lists'; + } +} +export class UserListMembershipsV2Paginator extends ListTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/list_memberships'; + } +} +export class UserListFollowedV2Paginator extends ListTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/followed_lists'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/mutes.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/mutes.paginator.v1.d.ts new file mode 100644 index 0000000..f54f937 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/mutes.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/mutes.paginator.v1.js new file mode 100644 index 0000000..c937fd2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/mutes.paginator.v1.js @@ -0,0 +1,54 @@ +import { CursoredV1Paginator } from './paginator.v1'; +export class MuteUserListV1Paginator extends 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; + } +} +export class MuteUserIdsV1Paginator extends 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; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/paginator.v1.d.ts new file mode 100644 index 0000000..fc55abb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/paginator.v1.js new file mode 100644 index 0000000..6cf1fb1 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/paginator.v1.js @@ -0,0 +1,26 @@ +import TwitterPaginator from './TwitterPaginator'; +export class CursoredV1Paginator extends TwitterPaginator { + 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'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v1.d.ts new file mode 100644 index 0000000..3172df6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/tweet.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v1.js new file mode 100644 index 0000000..e1e4b4b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v1.js @@ -0,0 +1,81 @@ +import TwitterPaginator from './TwitterPaginator'; +/** A generic TwitterPaginator able to consume TweetV1 timelines. */ +class TweetTimelineV1Paginator extends TwitterPaginator { + 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 +export class HomeTimelineV1Paginator extends TweetTimelineV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'statuses/home_timeline.json'; + } +} +// Mention +export class MentionTimelineV1Paginator extends TweetTimelineV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'statuses/mentions_timeline.json'; + } +} +// User +export class UserTimelineV1Paginator extends TweetTimelineV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'statuses/user_timeline.json'; + } +} +// Lists +export class ListTimelineV1Paginator extends TweetTimelineV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/statuses.json'; + } +} +// Favorites +export class UserFavoritesV1Paginator extends TweetTimelineV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'favorites/list.json'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v2.d.ts new file mode 100644 index 0000000..d0b4f6c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/tweet.paginator.v2.js b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v2.js new file mode 100644 index 0000000..29eb213 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/tweet.paginator.v2.js @@ -0,0 +1,193 @@ +import { TimelineV2Paginator, TwitterV2Paginator } from './v2.paginator'; +/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines with since_id, until_id and next_token (when available). */ +class TweetTimelineV2Paginator 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.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 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 - +// ---------------- +export class TweetSearchRecentV2Paginator extends TweetTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'tweets/search/recent'; + } +} +export class TweetSearchAllV2Paginator extends TweetTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'tweets/search/all'; + } +} +export class QuotedTweetsTimelineV2Paginator extends TweetPaginableTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'tweets/:id/quote_tweets'; + } +} +// ----------------- +// - Home timeline - +// ----------------- +export class TweetHomeTimelineV2Paginator extends TweetPaginableTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/timelines/reverse_chronological'; + } +} +export class TweetUserTimelineV2Paginator extends TweetPaginableTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/tweets'; + } +} +export class TweetUserMentionTimelineV2Paginator extends TweetPaginableTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/mentions'; + } +} +// ------------- +// - Bookmarks - +// ------------- +export class TweetBookmarksTimelineV2Paginator extends TweetPaginableTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/bookmarks'; + } +} +// --------------------------------------------------------------------------------- +// - Tweet lists (consume tweets with pagination tokens instead of since/until id) - +// --------------------------------------------------------------------------------- +/** A generic TwitterPaginator able to consume TweetV2 timelines. */ +class TweetListV2Paginator extends 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; + } +} +export class TweetV2UserLikedTweetsPaginator extends TweetListV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/liked_tweets'; + } +} +export class TweetV2ListTweetsPaginator extends TweetListV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/:id/tweets'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v1.d.ts new file mode 100644 index 0000000..4bcd0ff --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/user.paginator.v1.js b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v1.js new file mode 100644 index 0000000..72566c1 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v1.js @@ -0,0 +1,76 @@ +import TwitterPaginator from './TwitterPaginator'; +import { CursoredV1Paginator } from './paginator.v1'; +/** A generic TwitterPaginator able to consume TweetV1 timelines. */ +export class UserSearchV1Paginator extends TwitterPaginator { + 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; + } +} +export class FriendshipsIncomingV1Paginator extends 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; + } +} +export class FriendshipsOutgoingV1Paginator extends FriendshipsIncomingV1Paginator { + constructor() { + super(...arguments); + this._endpoint = 'friendships/outgoing.json'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v2.d.ts new file mode 100644 index 0000000..ba1cd0e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/user.paginator.v2.js b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v2.js new file mode 100644 index 0000000..755422d --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/user.paginator.v2.js @@ -0,0 +1,65 @@ +import { TimelineV2Paginator } from './v2.paginator'; +/** A generic PreviousableTwitterPaginator able to consume UserV2 timelines. */ +class UserTimelineV2Paginator extends 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; + } +} +export class UserBlockingUsersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/blocking'; + } +} +export class UserMutingUsersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/muting'; + } +} +export class UserFollowersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/followers'; + } +} +export class UserFollowingV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'users/:id/following'; + } +} +export class UserListMembersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/:id/members'; + } +} +export class UserListFollowersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'lists/:id/followers'; + } +} +export class TweetLikingUsersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'tweets/:id/liking_users'; + } +} +export class TweetRetweetersUsersV2Paginator extends UserTimelineV2Paginator { + constructor() { + super(...arguments); + this._endpoint = 'tweets/:id/retweeted_by'; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/paginators/v2.paginator.d.ts b/node_modules/twitter-api-v2/dist/esm/paginators/v2.paginator.d.ts new file mode 100644 index 0000000..1cdc52b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/paginators/v2.paginator.js b/node_modules/twitter-api-v2/dist/esm/paginators/v2.paginator.js new file mode 100644 index 0000000..35883a8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/paginators/v2.paginator.js @@ -0,0 +1,108 @@ +import { TwitterV2IncludesHelper } from '../v2/includes.v2.helper'; +import { PreviousableTwitterPaginator } from './TwitterPaginator'; +/** A generic PreviousableTwitterPaginator with common v2 helper methods. */ +export class TwitterV2Paginator extends 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 TwitterV2IncludesHelper(this._realData); + } + if (this._includesInstance) { + return this._includesInstance; + } + return this._includesInstance = new 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; + } +} +/** A generic TwitterV2Paginator able to consume v2 timelines that use max_results and pagination tokens. */ +export 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); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/plugins/helpers.d.ts b/node_modules/twitter-api-v2/dist/esm/plugins/helpers.d.ts new file mode 100644 index 0000000..264d053 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/plugins/helpers.js b/node_modules/twitter-api-v2/dist/esm/plugins/helpers.js new file mode 100644 index 0000000..41f1d66 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/plugins/helpers.js @@ -0,0 +1,41 @@ +import { ApiPartialResponseError, ApiRequestError, ApiResponseError, TwitterApiPluginResponseOverride } from '../types'; +/* Plugin helpers */ +export 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; +} +export async function applyResponseHooks(requestParams, computedParams, requestOptions, error) { + let override; + if (error instanceof ApiRequestError || error instanceof ApiPartialResponseError) { + override = await this.applyPluginMethod('onRequestError', { + client: this, + url: this.getUrlObjectFromUrlString(requestParams.url), + params: requestParams, + computedParams, + requestOptions, + error, + }); + } + else if (error instanceof ApiResponseError) { + override = await this.applyPluginMethod('onResponseError', { + client: this, + url: this.getUrlObjectFromUrlString(requestParams.url), + params: requestParams, + computedParams, + requestOptions, + error, + }); + } + if (override && override instanceof TwitterApiPluginResponseOverride) { + return override.value; + } + return Promise.reject(error); +} diff --git a/node_modules/twitter-api-v2/dist/esm/settings.d.ts b/node_modules/twitter-api-v2/dist/esm/settings.d.ts new file mode 100644 index 0000000..5a8d18e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/settings.js b/node_modules/twitter-api-v2/dist/esm/settings.js new file mode 100644 index 0000000..319ecfe --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/settings.js @@ -0,0 +1,5 @@ +export const TwitterApiV2Settings = { + debug: false, + deprecationWarnings: true, + logger: { log: console.log.bind(console) }, +}; diff --git a/node_modules/twitter-api-v2/dist/esm/stream/TweetStream.d.ts b/node_modules/twitter-api-v2/dist/esm/stream/TweetStream.d.ts new file mode 100644 index 0000000..d84cf71 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/stream/TweetStream.js b/node_modules/twitter-api-v2/dist/esm/stream/TweetStream.js new file mode 100644 index 0000000..12703ee --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/stream/TweetStream.js @@ -0,0 +1,273 @@ +import { EventEmitter } from 'events'; +import RequestHandlerHelper from '../client-mixins/request-handler.helper'; +import { ETwitterStreamEvent } from '../types'; +import TweetStreamEventCombiner from './TweetStreamEventCombiner'; +import TweetStreamParser, { EStreamParserEvent } from './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; +export class TweetStream extends 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(); + 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(ETwitterStreamEvent.ConnectionError, err); + this.emit(ETwitterStreamEvent.Error, { + type: 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(ETwitterStreamEvent.DataKeepAlive); + } + this.parser.push(chunk.toString()); + }); + // Starts the keep alive timeout + this.resetKeepAliveTimeout(); + } + initEventsFromParser() { + const payloadIsError = this.requestData.payloadIsError; + this.parser.on(EStreamParserEvent.ParsedData, (eventData) => { + if (payloadIsError && payloadIsError(eventData)) { + this.emit(ETwitterStreamEvent.DataError, eventData); + this.emit(ETwitterStreamEvent.Error, { + type: ETwitterStreamEvent.DataError, + error: eventData, + message: 'Twitter sent a payload that is detected as an error payload.', + }); + } + else { + this.emit(ETwitterStreamEvent.Data, eventData); + } + }); + this.parser.on(EStreamParserEvent.ParseError, (error) => { + this.emit(ETwitterStreamEvent.TweetParseError, error); + this.emit(ETwitterStreamEvent.Error, { + type: 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(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(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 RequestHandlerHelper(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(ETwitterStreamEvent.ConnectError, 0); + this.emit(ETwitterStreamEvent.Error, { + type: 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 RequestHandlerHelper(this.requestData).makeRequestAndResolveWhenReady(); + this.req = req; + this.res = res; + this.originalResponse = originalResponse; + this.emit(initialConnection ? ETwitterStreamEvent.Connected : 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(ETwitterStreamEvent.ConnectionClosed); + return; + } + if (retryOccurrence >= this.autoReconnectRetries) { + this.emit(ETwitterStreamEvent.ReconnectLimitExceeded); + this.emit(ETwitterStreamEvent.ConnectionClosed); + return; + } + // If all other conditions fails, do a reconnect attempt + try { + this.emit(ETwitterStreamEvent.ReconnectAttempt, retryOccurrence); + await this.reconnect(); + } + catch (e) { + this.emit(ETwitterStreamEvent.ReconnectError, retryOccurrence); + this.emit(ETwitterStreamEvent.Error, { + type: 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(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(); + } + } +} +export default TweetStream; diff --git a/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamEventCombiner.d.ts b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamEventCombiner.d.ts new file mode 100644 index 0000000..e268000 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/stream/TweetStreamEventCombiner.js b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamEventCombiner.js new file mode 100644 index 0000000..2b0b20b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamEventCombiner.js @@ -0,0 +1,51 @@ +import { EventEmitter } from 'events'; +import { ETwitterStreamEvent } from '../types'; +export class TweetStreamEventCombiner extends 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(ETwitterStreamEvent.Data, this.onStreamData); + // Ignore reconnect errors: Don't close event combiner until connection error/closed + stream.on(ETwitterStreamEvent.ConnectionError, this.onStreamError); + stream.on(ETwitterStreamEvent.TweetParseError, this.onStreamError); + stream.on(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(ETwitterStreamEvent.Data, this.onStreamData); + this.stream.off(ETwitterStreamEvent.ConnectionError, this.onStreamError); + this.stream.off(ETwitterStreamEvent.TweetParseError, this.onStreamError); + this.stream.off(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); + } +} +export default TweetStreamEventCombiner; diff --git a/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamParser.d.ts b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamParser.d.ts new file mode 100644 index 0000000..459fcbb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/stream/TweetStreamParser.js b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamParser.js new file mode 100644 index 0000000..e7840a1 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/stream/TweetStreamParser.js @@ -0,0 +1,50 @@ +import { EventEmitter } from 'events'; +export default class TweetStreamParser extends 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 = ''; + } +} +export var EStreamParserEvent; +(function (EStreamParserEvent) { + EStreamParserEvent["ParsedData"] = "parsed data"; + EStreamParserEvent["ParseError"] = "parse error"; +})(EStreamParserEvent || (EStreamParserEvent = {})); diff --git a/node_modules/twitter-api-v2/dist/esm/test/utils.d.ts b/node_modules/twitter-api-v2/dist/esm/test/utils.d.ts new file mode 100644 index 0000000..840fb61 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/test/utils.js b/node_modules/twitter-api-v2/dist/esm/test/utils.js new file mode 100644 index 0000000..2c17898 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/test/utils.js @@ -0,0 +1,65 @@ +import { TwitterApi } from '..'; +import * as dotenv from 'dotenv'; +dotenv.config({ path: __dirname + '/../../.env' }); +/** User OAuth 1.0a client */ +export function getUserClient() { + return new TwitterApi({ + appKey: process.env.CONSUMER_TOKEN, + appSecret: process.env.CONSUMER_SECRET, + accessToken: process.env.OAUTH_TOKEN, + accessSecret: process.env.OAUTH_SECRET, + }); +} +export function getUserKeys() { + return { + appKey: process.env.CONSUMER_TOKEN, + appSecret: process.env.CONSUMER_SECRET, + accessToken: process.env.OAUTH_TOKEN, + accessSecret: process.env.OAUTH_SECRET, + }; +} +export async function sleepTest(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} +/** User-unlogged OAuth 1.0a client */ +export function getRequestClient() { + return new TwitterApi({ + appKey: process.env.CONSUMER_TOKEN, + appSecret: process.env.CONSUMER_SECRET, + }); +} +export function getRequestKeys() { + return { + appKey: process.env.CONSUMER_TOKEN, + appSecret: process.env.CONSUMER_SECRET, + }; +} +// Test auth 1.0a flow +export function getAuthLink(callback) { + return getRequestClient().generateAuthLink(callback); +} +export async function getAccessClient(verifier) { + const requestClient = new 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; +} +/** App OAuth 2.0 client */ +export function getAppClient() { + let requestClient; + if (process.env.BEARER_TOKEN) { + requestClient = new TwitterApi(process.env.BEARER_TOKEN); + return Promise.resolve(requestClient); + } + else { + requestClient = new TwitterApi({ + appKey: process.env.CONSUMER_TOKEN, + appSecret: process.env.CONSUMER_SECRET, + }); + return requestClient.appLogin(); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/auth.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/auth.types.d.ts new file mode 100644 index 0000000..6f31060 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/types/auth.types.js b/node_modules/twitter-api-v2/dist/esm/types/auth.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/auth.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/client.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/client.types.d.ts new file mode 100644 index 0000000..b381234 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/types/client.types.js b/node_modules/twitter-api-v2/dist/esm/types/client.types.js new file mode 100644 index 0000000..e9937c6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/client.types.js @@ -0,0 +1,17 @@ +export 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 || (ETwitterStreamEvent = {})); diff --git a/node_modules/twitter-api-v2/dist/esm/types/entities.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/entities.types.d.ts new file mode 100644 index 0000000..2a3cbaa --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/types/entities.types.js b/node_modules/twitter-api-v2/dist/esm/types/entities.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/entities.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/errors.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/errors.types.d.ts new file mode 100644 index 0000000..5dc5a43 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/types/errors.types.js b/node_modules/twitter-api-v2/dist/esm/types/errors.types.js new file mode 100644 index 0000000..fdce163 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/errors.types.js @@ -0,0 +1,217 @@ +export var ETwitterApiError; +(function (ETwitterApiError) { + ETwitterApiError["Request"] = "request"; + ETwitterApiError["PartialResponse"] = "partial-response"; + ETwitterApiError["Response"] = "response"; +})(ETwitterApiError || (ETwitterApiError = {})); +/* ERRORS INSTANCES */ +class ApiError extends Error { + constructor() { + super(...arguments); + this.error = true; + } +} +export 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, + }; + } +} +export 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, + }; + } +} +export 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, + }; + } +} +export 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 || (EApiV1ErrorCode = {})); +export 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 || (EApiV2ErrorCode = {})); diff --git a/node_modules/twitter-api-v2/dist/esm/types/index.d.ts b/node_modules/twitter-api-v2/dist/esm/types/index.d.ts new file mode 100644 index 0000000..cfc014a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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/esm/types/index.js b/node_modules/twitter-api-v2/dist/esm/types/index.js new file mode 100644 index 0000000..f495a0a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/index.js @@ -0,0 +1,7 @@ +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'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.d.ts new file mode 100644 index 0000000..85ef5cc --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/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; +export declare type TTwitterApiResponseErrorHook = (args: ITwitterApiResponseErrorHookArgs) => PromiseOrType; +export declare type TTwitterApiBeforeStreamRequestConfigHook = (args: ITwitterApiBeforeRequestConfigHookArgs) => void; +export interface ITwitterApiAfterOAuth1RequestTokenHookArgs { + client: ClientRequestMaker; + url: string; + oauthResult: RequestTokenResult; +} +export interface ITwitterApiAfterOAuth2RequestTokenHookArgs { + client: ClientRequestMaker; + result: IOAuth2RequestTokenResult; + redirectUri: string; +} +export declare type TTwitterApiAfterOAuth1RequestTokenHook = (args: ITwitterApiAfterOAuth1RequestTokenHookArgs) => void | Promise; +export declare type TTwitterApiAfterOAuth2RequestTokenHook = (args: ITwitterApiAfterOAuth2RequestTokenHookArgs) => void | Promise; diff --git a/node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.js b/node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.js new file mode 100644 index 0000000..a911bb2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.js @@ -0,0 +1,5 @@ +export class TwitterApiPluginResponseOverride { + constructor(value) { + this.value = value; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/plugins/index.d.ts b/node_modules/twitter-api-v2/dist/esm/types/plugins/index.d.ts new file mode 100644 index 0000000..7459ee7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/plugins/index.d.ts @@ -0,0 +1 @@ +export * from './client.plugins.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/plugins/index.js b/node_modules/twitter-api-v2/dist/esm/types/plugins/index.js new file mode 100644 index 0000000..7459ee7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/plugins/index.js @@ -0,0 +1 @@ +export * from './client.plugins.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.d.ts new file mode 100644 index 0000000..8608561 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.d.ts @@ -0,0 +1,74 @@ +/// +/// +import type { RequestOptions } from 'https'; +import type { TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens } from './client.types'; +import type { TwitterRateLimit } from './responses.types'; +export declare type TRequestDebuggerHandlerEvent = 'abort' | 'close' | 'socket' | 'socket-error' | 'socket-connect' | 'socket-close' | 'socket-end' | 'socket-lookup' | 'socket-timeout' | 'request-error' | 'response' | 'response-aborted' | 'response-error' | 'response-close' | 'response-end'; +export declare type TRequestDebuggerHandler = (event: TRequestDebuggerHandlerEvent, data?: any) => void; +/** + * Request compression level. `true` means `'brotli'`, `false` means `'identity'`. + * When `brotli` is unavailable (f.e. in streams), it will fallback to `gzip`. + */ +export declare type TRequestCompressionLevel = boolean | 'brotli' | 'gzip' | 'deflate' | 'identity'; +export declare type TRequestFullData = { + url: URL; + options: RequestOptions; + body?: any; + rateLimitSaver?: (rateLimit: TwitterRateLimit) => any; + requestEventDebugHandler?: TRequestDebuggerHandler; + compression?: TRequestCompressionLevel; + forceParseMode?: TResponseParseMode; +}; +export declare type TRequestFullStreamData = TRequestFullData & { + payloadIsError?: (data: any) => boolean; +}; +export declare type TRequestQuery = Record; +export declare type TRequestStringQuery = Record; +export declare type TRequestBody = Record | Buffer; +export declare type TBodyMode = 'json' | 'url' | 'form-data' | 'raw'; +export declare type TResponseParseMode = 'json' | 'url' | 'text' | 'buffer' | 'none'; +export interface IWriteAuthHeadersArgs { + headers: Record; + bodyInSignature: boolean; + url: URL; + method: string; + query: TRequestQuery; + body: TRequestBody; +} +export interface IGetHttpRequestArgs { + url: string; + method: string; + query?: TRequestQuery; + /** The URL parameters, if you specify an endpoint with `:id`, for example. */ + params?: TRequestQuery; + body?: TRequestBody; + headers?: Record; + forceBodyMode?: TBodyMode; + forceParseMode?: TResponseParseMode; + enableAuth?: boolean; + enableRateLimitSave?: boolean; + timeout?: number; + requestEventDebugHandler?: TRequestDebuggerHandler; + compression?: TRequestCompressionLevel; +} +export interface IComputedHttpRequestArgs { + rawUrl: string; + url: URL; + method: string; + headers: Record; + body: string | Buffer | undefined; +} +export interface IGetStreamRequestArgs { + payloadIsError?: (data: any) => boolean; + autoConnect?: boolean; +} +export interface IGetStreamRequestArgsAsync { + payloadIsError?: (data: any) => boolean; + autoConnect?: true; +} +export interface IGetStreamRequestArgsSync { + payloadIsError?: (data: any) => boolean; + autoConnect: false; +} +export declare type TCustomizableRequestArgs = Pick; +export declare type TAcceptedInitToken = TwitterApiTokens | TwitterApiOAuth2Init | TwitterApiBasicAuth | string; diff --git a/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.js b/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/request-maker.mixin.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/responses.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/responses.types.d.ts new file mode 100644 index 0000000..2abfbb2 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/responses.types.d.ts @@ -0,0 +1,12 @@ +/// +import type { IncomingHttpHeaders } from 'http'; +export interface TwitterResponse { + headers: IncomingHttpHeaders; + data: T; + rateLimit?: TwitterRateLimit; +} +export interface TwitterRateLimit { + limit: number; + reset: number; + remaining: number; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/responses.types.js b/node_modules/twitter-api-v2/dist/esm/types/responses.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/responses.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/shared.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/shared.types.d.ts new file mode 100644 index 0000000..f0538d7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/shared.types.d.ts @@ -0,0 +1,4 @@ +export declare type NumberString = number | string; +export declare type BooleanString = boolean | string; +export declare type TypeOrArrayOf = T | T[]; +export declare type PromiseOrType = T | Promise; diff --git a/node_modules/twitter-api-v2/dist/esm/types/shared.types.js b/node_modules/twitter-api-v2/dist/esm/types/shared.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/shared.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.d.ts new file mode 100644 index 0000000..8d89b69 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.d.ts @@ -0,0 +1,21 @@ +export declare type TAppRateLimitResourceV1 = 'help' | 'statuses' | 'friends' | 'followers' | 'users' | 'search' | 'trends' | 'favorites' | 'friendships' | 'direct_messages' | 'lists' | 'geo' | 'account' | 'application' | 'account_activity'; +export interface AppRateLimitV1Result { + rate_limit_context: { + access_token: string; + }; + resources: { + [TResourceName in TAppRateLimitResourceV1]?: { + [resourceEndpoint: string]: AppRateLimitEndpointV1; + }; + }; +} +export interface AppRateLimitEndpointV1 { + limit: number; + remaining: number; + reset: number; +} +export interface HelpLanguageV1Result { + code: string; + status: string; + name: string; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/dev-utilities.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.d.ts new file mode 100644 index 0000000..c6aeb80 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.d.ts @@ -0,0 +1,162 @@ +import { CoordinateV1, MediaEntityV1, TweetEntitiesV1 } from './entities.v1.types'; +export declare enum EDirectMessageEventTypeV1 { + Create = "message_create", + WelcomeCreate = "welcome_message" +} +export interface MessageCreateEventV1 { + target: { + recipient_id: string; + }; + message_data: MessageCreateDataV1; + custom_profile_id?: string; +} +export interface MessageCreateDataV1 { + text: string; + attachment?: MessageCreateAttachmentV1; + quick_reply?: MessageCreateQuickReplyV1; + ctas?: MessageCreateCtaV1[]; +} +export interface MessageCreateCtaV1 { + type: 'web_url'; + url: string; + label: string; + /** Only when messages are retrieved from API */ + tco_url?: string; +} +export interface MessageCreateQuickReplyOptionV1 { + label: string; + description?: string; + metadata?: string; +} +export interface MessageCreateQuickReplyV1 { + type: 'options'; + options: MessageCreateQuickReplyOptionV1[]; +} +export declare type MessageCreateAttachmentV1 = { + type: 'media'; + media: { + id: string; + }; +} | { + type: 'location'; + location: MessageCreateLocationV1; +}; +export declare type MessageCreateLocationV1 = { + type: 'shared_coordinate'; + shared_coordinate: { + coordinates: CoordinateV1; + }; +} | { + type: 'shared_place'; + shared_place: { + place: { + id: string; + }; + }; +}; +export interface SendDMV1Params extends MessageCreateDataV1 { + recipient_id: string; + custom_profile_id?: string; +} +export interface CreateDMEventV1Args { + event: CreateDMEventV1; +} +export interface CreateDMEventV1 { + type: EDirectMessageEventTypeV1; + [EDirectMessageEventTypeV1.Create]?: MessageCreateEventV1; +} +export interface GetDmListV1Args { + cursor?: string; + count?: number; +} +export interface CreateWelcomeDMEventV1Args { + [EDirectMessageEventTypeV1.WelcomeCreate]: { + name: string; + message_data: MessageCreateDataV1; + }; +} +export interface DirectMessageCreateV1 extends ReceivedDirectMessageEventV1 { + type: EDirectMessageEventTypeV1.Create; + [EDirectMessageEventTypeV1.Create]: ReceivedMessageCreateEventV1; +} +export interface ReceivedDirectMessageEventV1 { + type: EDirectMessageEventTypeV1; + id: string; + created_timestamp: string; + initiated_via?: { + tweet_id?: string; + welcome_message_id?: string; + }; +} +export interface ReceivedMessageCreateEventV1 { + target: { + recipient_id: string; + }; + sender_id: string; + source_app_id: string; + message_data: ReceivedMessageCreateDataV1; + custom_profile_id?: string; +} +export interface ReceivedMessageCreateDataV1 { + text: string; + entities: TweetEntitiesV1; + quick_reply_response?: { + type: 'options'; + metadata?: string; + }; + attachment?: { + type: 'media'; + media: MediaEntityV1; + }; + quick_reply?: MessageCreateQuickReplyV1; + ctas?: MessageCreateCtaV1[]; +} +export interface ReceivedWelcomeDMCreateEventV1 { + id: string; + created_timestamp: string; + message_data: ReceivedMessageCreateDataV1; + name?: string; +} +export declare type DirectMessageCreateV1Result = { + event: DirectMessageCreateV1; +} & ReceivedDMAppsV1; +export interface ReceivedDMAppsV1 { + apps?: ReceivedDMAppListV1; +} +export declare type TReceivedDMEvent = DirectMessageCreateV1; +export interface ReceivedDMEventV1 extends ReceivedDMAppsV1 { + event: TReceivedDMEvent; +} +export interface ReceivedDMEventsV1 extends ReceivedDMAppsV1 { + next_cursor?: string; + events: TReceivedDMEvent[]; +} +export interface ReceivedDMAppListV1 { + [appId: string]: { + id: string; + name: string; + url: string; + }; +} +export interface WelcomeDirectMessageCreateV1Result extends ReceivedDMAppsV1 { + [EDirectMessageEventTypeV1.WelcomeCreate]: ReceivedWelcomeDMCreateEventV1; + name?: string; +} +export interface WelcomeDirectMessageListV1Result extends ReceivedDMAppsV1 { + next_cursor?: string; + welcome_messages: ReceivedWelcomeDMCreateEventV1[]; +} +export interface CreateWelcomeDmRuleV1 { + welcome_message_id: string; +} +export interface WelcomeDmRuleV1 extends CreateWelcomeDmRuleV1 { + id: string; + created_timestamp: string; +} +export interface WelcomeDmRuleV1Result { + welcome_message_rule: WelcomeDmRuleV1; +} +export interface WelcomeDmRuleListV1Result { + next_cursor?: string; + welcome_message_rules?: WelcomeDmRuleV1[]; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.js new file mode 100644 index 0000000..ac5d938 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.js @@ -0,0 +1,6 @@ +// Creation of DMs +export var EDirectMessageEventTypeV1; +(function (EDirectMessageEventTypeV1) { + EDirectMessageEventTypeV1["Create"] = "message_create"; + EDirectMessageEventTypeV1["WelcomeCreate"] = "welcome_message"; +})(EDirectMessageEventTypeV1 || (EDirectMessageEventTypeV1 = {})); diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.d.ts new file mode 100644 index 0000000..3f28838 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.d.ts @@ -0,0 +1,142 @@ +export interface TweetEntitiesV1 { + hashtags?: HashtagEntityV1[]; + urls?: UrlEntityV1[]; + user_mentions?: MentionEntityV1[]; + symbols?: SymbolEntityV1[]; + media?: MediaEntityV1[]; + polls?: [PollEntityV1]; +} +export interface TweetExtendedEntitiesV1 { + media?: MediaEntityV1[]; +} +export interface UserEntitiesV1 { + url?: { + urls: UrlEntityV1[]; + }; + description?: { + urls: UrlEntityV1[]; + }; +} +export interface UrlEntityV1 { + display_url: string; + expanded_url: string; + indices: [number, number]; + url: string; + unwound?: { + url: string; + status: number; + title: string; + description: string; + }; +} +export interface MediaEntityV1 { + display_url: string; + expanded_url: string; + url: string; + id: number; + id_str: string; + indices: [number, number]; + media_url: string; + media_url_https: string; + sizes: MediaSizesV1; + source_status_id: number; + source_status_id_str: string; + source_user_id: number; + source_user_id_str: string; + type: 'photo' | 'video' | 'animated_gif'; + video_info?: MediaVideoInfoV1; + additional_media_info?: AdditionalMediaInfoV1; + ext_alt_text?: string; +} +export interface MediaVideoInfoV1 { + aspect_ratio: [number, number]; + duration_millis: number; + variants: { + bitrate: number; + content_type: string; + url: string; + }[]; +} +export interface AdditionalMediaInfoV1 { + title: string; + description: string; + embeddable: boolean; + monetizable: boolean; +} +export interface MediaSizesV1 { + thumb: MediaSizeObjectV1; + large: MediaSizeObjectV1; + medium: MediaSizeObjectV1; + small: MediaSizeObjectV1; +} +export interface MediaSizeObjectV1 { + w: number; + h: number; + resize: 'crop' | 'fit'; +} +export interface HashtagEntityV1 { + indices: [number, number]; + text: string; +} +export interface MentionEntityV1 { + id: number; + id_str: string; + indices: [number, number]; + name: string; + screen_name: string; +} +export interface SymbolEntityV1 { + indices: [number, number]; + text: string; +} +export interface PollEntityV1 { + options: PollPositionV1[]; + end_datetime: string; + duration_minutes: number; +} +export interface PollPositionV1 { + position: number; + text: string; +} +/** See GeoJSON. */ +export interface CoordinateV1 { + coordinates: number[] | number[][]; + type: string; +} +export interface PlaceV1 { + full_name: string; + id: string; + url: string; + country: string; + country_code: string; + bounding_box: CoordinateV1; + name: string; + place_type: string; + contained_within?: PlaceV1[]; + geometry?: any; + polylines?: number[]; + centroid?: number[]; + attributes?: { + geotagCount: string; + [geoTagId: string]: string; + }; +} +export interface TrendV1 { + name: string; + url: string; + promoted_content?: boolean; + query: string; + tweet_volume: number; +} +export interface TrendLocationV1 { + name: string; + woeid: number; + url?: string; + placeType?: { + code: number; + name: string; + }; + parentid?: number; + country?: string; + countryCode?: string; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/entities.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.d.ts new file mode 100644 index 0000000..658f149 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.d.ts @@ -0,0 +1,32 @@ +import { PlaceV1 } from './entities.v1.types'; +export interface ReverseGeoCodeV1Params { + lat: number; + long: number; + accuracy?: string; + granularity?: 'city' | 'neighborhood' | 'country' | 'admin'; + max_results?: number; +} +export interface ReverseGeoCodeV1Result { + query: { + params: Partial; + type: string; + url: string; + }; + result: { + places: PlaceV1[]; + }; +} +export interface SearchGeoV1Params extends Partial { + ip?: string; + query?: string; +} +export interface SearchGeoV1Result { + query: { + params: SearchGeoV1Params; + type: string; + url: string; + }; + result: { + places: PlaceV1[]; + }; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/geo.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/index.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/index.d.ts new file mode 100644 index 0000000..51d26b8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/index.d.ts @@ -0,0 +1,9 @@ +export * from './streaming.v1.types'; +export * from './tweet.v1.types'; +export * from './entities.v1.types'; +export * from './user.v1.types'; +export * from './dev-utilities.v1.types'; +export * from './geo.v1.types'; +export * from './trends.v1.types'; +export * from './dm.v1.types'; +export * from './list.v1.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/index.js b/node_modules/twitter-api-v2/dist/esm/types/v1/index.js new file mode 100644 index 0000000..51d26b8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/index.js @@ -0,0 +1,9 @@ +export * from './streaming.v1.types'; +export * from './tweet.v1.types'; +export * from './entities.v1.types'; +export * from './user.v1.types'; +export * from './dev-utilities.v1.types'; +export * from './geo.v1.types'; +export * from './trends.v1.types'; +export * from './dm.v1.types'; +export * from './list.v1.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.d.ts new file mode 100644 index 0000000..bf43789 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.d.ts @@ -0,0 +1,87 @@ +import { TweetV1TimelineParams } from './tweet.v1.types'; +import { UserV1 } from './user.v1.types'; +export interface ListV1 { + id: number; + id_str: string; + slug: string; + name: string; + full_name: string; + created_at: string; + description: string; + uri: string; + subscriber_count: number; + member_count: number; + mode: 'public' | 'private'; + user: UserV1; +} +declare type TUserOrScreenName = { + user_id: string; +} | { + screen_name: string; +}; +export declare type ListListsV1Params = Partial & { + reverse?: boolean; +}; +export interface GetListV1Params { + list_id?: string; + slug?: string; + owner_screen_name?: string; + owner_id?: string; +} +export interface ListMemberShowV1Params extends GetListV1Params { + include_entities?: boolean; + skip_status?: boolean; + user_id?: string; + screen_name?: string; + tweet_mode?: 'compat' | 'extended'; +} +export interface ListMembersV1Params extends GetListV1Params { + count?: number; + cursor?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'compat' | 'extended'; +} +export interface ListOwnershipsV1Params { + user_id?: string; + screen_name?: string; + count?: number; + cursor?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'compat' | 'extended'; +} +export declare type ListSubscriptionsV1Params = ListOwnershipsV1Params; +export interface ListMembershipsV1Params extends ListOwnershipsV1Params { + filter_to_owned_lists?: boolean; +} +export interface ListStatusesV1Params extends TweetV1TimelineParams, GetListV1Params { + include_rts?: boolean; +} +export interface ListCreateV1Params { + name: string; + mode?: 'public' | 'private'; + description?: string; + tweet_mode?: 'compat' | 'extended'; +} +export interface AddOrRemoveListMembersV1Params extends GetListV1Params { + user_id?: string | string[]; + screen_name?: string | string[]; +} +export interface UpdateListV1Params extends Partial, GetListV1Params { +} +export interface DoubleEndedListsCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + lists: ListV1[]; +} +export interface DoubleEndedUsersCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/list.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.d.ts new file mode 100644 index 0000000..1a928a6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.d.ts @@ -0,0 +1,27 @@ +import type { TypeOrArrayOf } from '../shared.types'; +export interface AskTweetStreamV1Params { + tweet_mode?: 'extended' | 'compat'; + /** Specifies whether stall warnings should be delivered. */ + stall_warnings: boolean; +} +/** + * See https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/guides/basic-stream-parameters + * for detailed documentation. + */ +export interface FilterStreamV1Params extends AskTweetStreamV1Params { + /** A list of user IDs, indicating the users to return statuses for in the stream. */ + follow: TypeOrArrayOf<(string | BigInt)>; + /** Keywords to track. */ + track: TypeOrArrayOf; + /** Specifies a set of bounding boxes to track. */ + locations: TypeOrArrayOf<{ + lng: string; + lat: string; + }>; + /** Specifies whether stall warnings should be delivered. */ + stall_warnings: boolean; + [otherParameter: string]: any; +} +export interface SampleStreamV1Params extends AskTweetStreamV1Params { + [otherParameter: string]: any; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/streaming.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.d.ts new file mode 100644 index 0000000..7d4f61a --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.d.ts @@ -0,0 +1,10 @@ +import { TrendLocationV1, TrendV1 } from './entities.v1.types'; +export interface TrendsPlaceV1Params { + exclude: string; +} +export interface TrendMatchV1 { + trends: TrendV1[]; + as_of: string; + created_at: string; + locations: TrendLocationV1[]; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/trends.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.d.ts new file mode 100644 index 0000000..48815d7 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.d.ts @@ -0,0 +1,201 @@ +/// +/// +import type * as fs from 'fs'; +import type { BooleanString, NumberString } from '../shared.types'; +import { CoordinateV1, PlaceV1, TweetEntitiesV1, TweetExtendedEntitiesV1 } from './entities.v1.types'; +import { UserV1 } from './user.v1.types'; +export interface TweetV1 { + created_at: string; + id: number; + id_str: string; + text: string; + full_text?: string; + source: string; + truncated: boolean; + in_reply_to_status_id: number | null; + in_reply_to_status_id_str: string | null; + in_reply_to_user_id: number | null; + in_reply_to_user_id_str: string | null; + in_reply_to_screen_name: string | null; + user: UserV1; + coordinates: CoordinateV1 | null; + place: PlaceV1 | null; + quoted_status_id: number; + quoted_status_id_str: string; + is_quote_status: boolean; + quoted_status?: TweetV1; + retweeted_status?: TweetV1; + quote_count?: number; + reply_count?: number; + retweet_count: number; + favorite_count: number; + entities: TweetEntitiesV1; + extended_entities?: TweetExtendedEntitiesV1; + favorited: boolean | null; + retweeted: boolean; + possibly_sensitive: boolean | null; + filter_level: 'none' | 'low' | 'medium' | 'high'; + lang: string; + display_text_range?: [number, number]; + current_user_retweet?: { + id: number; + id_str: string; + }; + withheld_copyright?: boolean; + withheld_in_countries?: string[]; + withheld_scope?: string; + card_uri?: string; +} +export interface TweetShowV1Params { + tweet_mode?: 'compat' | 'extended'; + id?: string; + trim_user?: boolean; + include_my_retweet?: boolean; + include_entities?: boolean; + include_ext_alt_text?: boolean; + include_card_uri?: boolean; +} +export declare type TweetLookupV1Params = { + id?: string | string[]; + map?: boolean; +} & Omit; +export declare type TweetLookupNoMapV1Params = TweetLookupV1Params & { + map?: false; +}; +export declare type TweetLookupMapV1Params = TweetLookupV1Params & { + map: true; +}; +export interface AskTweetV1Params { + tweet_mode?: 'extended' | 'compat'; + include_entities?: boolean; + trim_user?: boolean; +} +export interface TweetV1TimelineParams extends AskTweetV1Params { + count?: number; + since_id?: string; + max_id?: string; + exclude_replies?: boolean; +} +export interface TweetV1UserTimelineParams extends TweetV1TimelineParams { + user_id?: string; + screen_name?: string; + include_rts?: boolean; +} +export interface SendTweetV1Params extends AskTweetV1Params { + status: string; + in_reply_to_status_id?: string; + auto_populate_reply_metadata?: BooleanString; + exclude_reply_user_ids?: string; + attachment_url?: string; + media_ids?: string | string[]; + possibly_sensitive?: BooleanString; + lat?: NumberString; + long?: NumberString; + display_coordinates?: BooleanString; + enable_dmcommands?: BooleanString; + fail_dmcommands?: BooleanString; + card_uri?: string; + place_id?: string; +} +export declare type TUploadTypeV1 = 'mp4' | 'longmp4' | 'mov' | 'gif' | 'jpg' | 'png' | 'srt' | 'webp'; +export declare enum EUploadMimeType { + Jpeg = "image/jpeg", + Mp4 = "video/mp4", + Mov = "video/quicktime", + Gif = "image/gif", + Png = "image/png", + Srt = "text/plain", + Webp = "image/webp" +} +export interface UploadMediaV1Params { + /** @deprecated Directly use `mimeType` parameter with one of the allowed MIME types in `EUploadMimeType`. */ + type: TUploadTypeV1 | string; + mimeType: EUploadMimeType | string; + target: 'tweet' | 'dm'; + chunkLength: number; + shared: boolean; + longVideo: boolean; + additionalOwners: string | string[]; + maxConcurrentUploads: number; +} +export interface MediaMetadataV1Params { + alt_text?: { + text: string; + }; +} +export interface MediaSubtitleV1Param { + media_id: string; + language_code: string; + display_name: string; +} +/** + * Link to a file that is usable as media. + * - `string`: File path + * - `Buffer`: File content, as binary buffer + * - `fs.promises.FileHandle`: Opened file with `fs.promises` + * - `number`: Opened file with `fs` classic functions + */ +export declare type TUploadableMedia = string | Buffer | fs.promises.FileHandle | number; +export interface OembedTweetV1Params { + url: string; + maxwidth?: number; + hide_media?: boolean; + hide_thread?: boolean; + omit_script?: boolean; + align?: 'left' | 'right' | 'center' | 'none'; + related?: string; + lang?: string; + theme?: 'light' | 'dark'; + link_color?: string; + widget_type?: 'video'; + dnt?: boolean; +} +export declare type TweetV1TimelineResult = TweetV1[]; +export interface InitMediaV1Result { + media_id: number; + media_id_string: string; + size: number; + expires_after_secs: number; + image: { + image_type: string; + w: number; + h: number; + }; +} +export interface MediaStatusV1Result { + media_id: number; + media_id_string: string; + size: number; + expires_after_secs: number; + video?: { + video_type: string; + }; + processing_info?: { + state: 'pending' | 'failed' | 'succeeded' | 'in_progress'; + check_after_secs?: number; + progress_percent?: number; + error?: { + code: number; + name: string; + message: string; + }; + }; +} +export interface OembedTweetV1Result { + url: string; + author_name: string; + author_url: string; + html: string; + width: number; + height: number | null; + type: string; + cache_age: string; + provider_name: string; + provider_url: string; + version: string; +} +export interface TweetLookupMapV1Result { + id: { + [tweetId: string]: TweetV1 | null; + }; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.js new file mode 100644 index 0000000..284b718 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.js @@ -0,0 +1,10 @@ +export var EUploadMimeType; +(function (EUploadMimeType) { + EUploadMimeType["Jpeg"] = "image/jpeg"; + EUploadMimeType["Mp4"] = "video/mp4"; + EUploadMimeType["Mov"] = "video/quicktime"; + EUploadMimeType["Gif"] = "image/gif"; + EUploadMimeType["Png"] = "image/png"; + EUploadMimeType["Srt"] = "text/plain"; + EUploadMimeType["Webp"] = "image/webp"; +})(EUploadMimeType || (EUploadMimeType = {})); diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.d.ts new file mode 100644 index 0000000..3d42368 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.d.ts @@ -0,0 +1,262 @@ +import { UserEntitiesV1 } from './entities.v1.types'; +import { TweetV1 } from './tweet.v1.types'; +export interface UserV1 { + id_str: string; + id: number; + name: string; + screen_name: string; + location: string; + derived?: any; + url: string | null; + description: string | null; + protected: boolean; + verified: boolean; + followers_count: number; + friends_count: number; + listed_count: number; + favourites_count: number; + statuses_count: number; + created_at: string; + profile_banner_url: string; + profile_image_url_https: string; + default_profile: boolean; + default_profile_image: boolean; + withheld_in_countries: string[]; + withheld_scope: string; + entities?: UserEntitiesV1; + /** Only on account/verify_credentials with include_email: true */ + email?: string; +} +declare type TUserIdOrScreenName = { + user_id: string; +} | { + screen_name: string; +}; +declare type TUserObjectParams = { + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'extended' | 'compat'; +}; +export interface DoubleEndedIdCursorV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + ids: string[]; +} +export interface DoubleEndedIdCursorV1Params { + stringify_ids?: boolean; + cursor?: string; +} +export interface UserFollowingsIdsV1Params extends DoubleEndedIdCursorV1Params { + screen_name?: string; + user_id?: string; + count?: number; +} +export interface UserFollowerIdsV1Params extends DoubleEndedIdCursorV1Params { + screen_name?: string; + user_id?: string; + count?: number; +} +interface UserListV1Params { + screen_name?: string; + user_id?: string; + count?: number; + cursor?: string; + skip_status?: boolean; + include_user_entities: boolean; +} +export declare type UserFollowerListV1Params = UserListV1Params; +export declare type UserFriendListV1Params = UserListV1Params; +export interface VerifyCredentialsV1Params { + include_entities?: boolean; + skip_status?: boolean; + include_email?: boolean; +} +export interface MuteUserListV1Params { + cursor?: string; + include_entities?: boolean; + skip_status?: string; + tweet_mode?: 'extended'; +} +export declare type MuteUserIdsV1Params = DoubleEndedIdCursorV1Params; +export interface ReportSpamV1Params { + screen_name?: string; + user_id?: string; + perform_block?: boolean; +} +export interface UserSearchV1Params { + q?: string; + page?: number; + count?: number; + include_entities?: boolean; + tweet_mode?: 'extended'; +} +export interface AccountSettingsV1Params { + sleep_time_enabled?: boolean; + start_sleep_time?: number; + end_sleep_time?: number; + time_zone?: string; + trend_location_woeid?: number; + lang?: string; +} +export interface AccountProfileV1Params { + name?: string; + url?: string; + location?: string; + description?: string; + profile_link_color?: string; + include_entities?: boolean; + skip_status?: boolean; + tweet_mode?: 'extended'; +} +export declare type ProfileBannerSizeV1Params = TUserIdOrScreenName; +export interface ProfileBannerUpdateV1Params { + width?: number; + height?: number; + offset_left?: number; + offset_top?: number; +} +export declare type ProfileImageUpdateV1Params = TUserObjectParams; +export interface FriendshipShowV1Params { + source_id?: string; + source_screen_name?: string; + target_id?: string; + target_screen_name?: string; +} +export interface FriendshipLookupV1Params { + screen_name?: string | string[]; + user_id?: string | string[]; +} +export declare type FriendshipsIncomingV1Params = DoubleEndedIdCursorV1Params; +export interface FriendshipUpdateV1Params { + screen_name?: string; + user_id?: string; + device?: boolean; + retweets?: boolean; +} +export interface FriendshipCreateV1Params { + screen_name?: string; + user_id?: string; + follow?: boolean; +} +export interface FriendshipDestroyV1Params { + screen_name?: string; + user_id?: string; +} +export declare type UserShowV1Params = TUserIdOrScreenName & TUserObjectParams; +export declare type UserLookupV1Params = { + user_id?: string | string[]; + screen_name?: string | string[]; +} & TUserObjectParams; +export interface MuteUserListV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export declare type MuteUserIdsV1Result = DoubleEndedIdCursorV1Result; +export declare type UserFollowerIdsV1Result = DoubleEndedIdCursorV1Result; +export declare type UserFollowingIdsV1Result = DoubleEndedIdCursorV1Result; +interface UserListV1Result { + next_cursor?: string; + next_cursor_str?: string; + previous_cursor?: string; + previous_cursor_str?: string; + users: UserV1[]; +} +export declare type UserFollowerListV1Result = UserListV1Result; +export declare type UserFriendListV1Result = UserListV1Result; +export interface BannerSizeV1 { + h: number; + w: number; + url: string; +} +export interface ProfileBannerSizeV1 { + sizes: { + ipad: BannerSizeV1; + ipad_retina: BannerSizeV1; + web: BannerSizeV1; + web_retina: BannerSizeV1; + mobile: BannerSizeV1; + mobile_retina: BannerSizeV1; + '300x100': BannerSizeV1; + '600x200': BannerSizeV1; + '1500x500': BannerSizeV1; + }; +} +export interface AccountSettingsV1 { + time_zone: { + name: string; + utc_offset: number; + tzinfo_name: string; + }; + protected: boolean; + screen_name: string; + always_use_https: boolean; + use_cookie_personalization: boolean; + sleep_time: { + enabled: boolean; + end_time: string | null; + start_time: string | null; + }; + geo_enabled: boolean; + language: string; + discoverable_by_email: boolean; + discoverable_by_mobile_phone: boolean; + display_sensitive_media: boolean; + allow_contributor_request: 'all' | 'following' | string; + allow_dms_from: 'all' | 'following' | string; + allow_dm_groups_from: 'all' | 'following' | string; + translator_type: string; + trend_location: { + name: string; + countryCode: string; + url: string; + woeid: number; + placeType: { + name: string; + code: number; + }; + parentid: number | null; + country: string; + }[]; +} +export declare type TFriendshipConnectionV1 = 'following' | 'following_requested' | 'followed_by' | 'none' | 'blocking' | 'muting'; +export interface FriendshipRelationObjectV1 { + id: number; + id_str: string; + screen_name: string; + following: boolean; + followed_by: boolean; + live_following?: boolean; + following_received: boolean | null; + following_requested: boolean | null; + notifications_enabled?: boolean | null; + can_dm?: boolean | null; + blocking?: boolean | null; + blocked_by?: boolean | null; + muting?: boolean | null; + want_retweets?: boolean | null; + all_replies?: boolean | null; + marked_spam?: boolean | null; +} +export interface FriendshipV1 { + relationship: { + source: FriendshipRelationObjectV1; + target: FriendshipRelationObjectV1; + }; +} +export interface FriendshipCreateOrDestroyV1 extends UserV1 { + status: TweetV1; +} +export interface FriendshipLookupV1 { + name: string; + screen_name: string; + id: number; + id_str: string; + connections: TFriendshipConnectionV1[]; +} +export declare type FriendshipsIncomingV1Result = DoubleEndedIdCursorV1Result; +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.js b/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v1/user.v1.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.d.ts new file mode 100644 index 0000000..d45cb8c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.d.ts @@ -0,0 +1,50 @@ +import { TypeOrArrayOf } from '../shared.types'; +import { TTweetv2MediaField, TTweetv2TweetField, TTweetv2UserField } from './tweet.v2.types'; +import { ApiV2Includes, ReferencedTweetV2 } from './tweet.definition.v2'; +import { DataMetaAndIncludeV2, PaginableCountMetaV2 } from './shared.v2.types'; +export declare type TDMEventV2Field = 'created_at' | 'follower_count' | 'member_count' | 'private' | 'description' | 'owner_id'; +export declare type TDMEventV2Expansion = 'attachments.media_keys' | 'referenced_tweets.id' | 'sender_id' | 'participant_ids'; +export declare type TDMEventV2EventType = 'MessageCreate' | 'ParticipantsJoin' | 'ParticipantsLeave'; +export interface GetDMEventV2Params { + 'dm_event.fields': TypeOrArrayOf | string; + event_types: TypeOrArrayOf | string; + expansions: TypeOrArrayOf | string; + max_results: number; + 'media.fields': TypeOrArrayOf | string; + pagination_token: string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export declare type GetDMEventV2Result = DataMetaAndIncludeV2; +export interface PostDMInConversationParams { + attachments?: [{ + media_id: string; + }]; + text?: string; +} +export interface CreateDMConversationParams { + conversation_type: 'Group'; + participant_ids: string[]; + message: PostDMInConversationParams; +} +export interface PostDMInConversationResult { + dm_conversation_id: string; + dm_event_id: string; +} +export interface BaseDMEventV2 { + id: string; + created_at?: string; + sender_id?: string; + dm_conversation_id?: string; + attachments?: DMEventAttachmentV2; + referenced_tweets?: ReferencedTweetV2[]; +} +export interface DMEventAttachmentV2 { + media_keys: string[]; +} +export declare type DMEventV2 = ({ + event_type: 'MessageCreate'; + text: string; +} & BaseDMEventV2) | ({ + event_type: Extract; +} & BaseDMEventV2); diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/dm.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/index.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/index.d.ts new file mode 100644 index 0000000..c3d2677 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/index.d.ts @@ -0,0 +1,6 @@ +export * from './streaming.v2.types'; +export * from './tweet.v2.types'; +export * from './tweet.definition.v2'; +export * from './user.v2.types'; +export * from './spaces.v2.types'; +export * from './list.v2.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/index.js b/node_modules/twitter-api-v2/dist/esm/types/v2/index.js new file mode 100644 index 0000000..c3d2677 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/index.js @@ -0,0 +1,6 @@ +export * from './streaming.v2.types'; +export * from './tweet.v2.types'; +export * from './tweet.definition.v2'; +export * from './user.v2.types'; +export * from './spaces.v2.types'; +export * from './list.v2.types'; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.d.ts new file mode 100644 index 0000000..bd51fd0 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.d.ts @@ -0,0 +1,57 @@ +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2, DataV2, PaginableCountMetaV2 } from './shared.v2.types'; +import type { TTweetv2UserField } from './tweet.v2.types'; +import type { UserV2 } from './user.v2.types'; +export declare type TListV2Field = 'created_at' | 'follower_count' | 'member_count' | 'private' | 'description' | 'owner_id'; +export declare type TListV2Expansion = 'owner_id'; +export declare type TListV2Includes = { + users?: UserV2[]; +}; +export interface ListV2 { + id: string; + name: string; + created_at?: string; + private?: boolean; + follower_count?: number; + member_count?: number; + owner_id?: string; + description?: string; +} +export interface ListCreateV2Params { + name: string; + description?: string; + private?: boolean; +} +export interface GetListV2Params { + expansions: TypeOrArrayOf | string; + 'list.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface GetListTimelineV2Params extends Partial { + max_results?: number; + pagination_token?: string; +} +export declare type ListGetV2Result = DataAndIncludeV2; +export declare type ListTimelineV2Result = DataMetaAndIncludeV2; +export declare type ListCreateV2Result = DataV2<{ + id: string; + name: string; +}>; +export declare type ListUpdateV2Params = Omit & { + name?: string; +}; +export declare type ListUpdateV2Result = DataV2<{ + updated: true; +}>; +export declare type ListDeleteV2Result = DataV2<{ + deleted: true; +}>; +export declare type ListMemberV2Result = DataV2<{ + is_member: boolean; +}>; +export declare type ListFollowV2Result = DataV2<{ + following: boolean; +}>; +export declare type ListPinV2Result = DataV2<{ + pinned: boolean; +}>; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/list.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.d.ts new file mode 100644 index 0000000..daa80b6 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.d.ts @@ -0,0 +1,38 @@ +import type { InlineErrorV2 } from '../errors.types'; +export declare type MetaV2 = { + meta: M; + errors?: InlineErrorV2[]; +}; +export declare type DataV2 = { + data: D; + errors?: InlineErrorV2[]; +}; +export declare type IncludeV2 = { + includes?: I; + errors?: InlineErrorV2[]; +}; +export declare type DataAndMetaV2 = { + data: D; + meta: M; + errors?: InlineErrorV2[]; +}; +export declare type DataAndIncludeV2 = { + data: D; + includes?: I; + errors?: InlineErrorV2[]; +}; +export declare type DataMetaAndIncludeV2 = { + data: D; + meta: M; + includes?: I; + errors?: InlineErrorV2[]; +}; +export interface SentMeta { + /** The time when the request body was returned. */ + sent: string; +} +export interface PaginableCountMetaV2 { + result_count: number; + next_token?: string; + previous_token?: string; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/shared.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.d.ts new file mode 100644 index 0000000..2518599 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.d.ts @@ -0,0 +1,50 @@ +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2 } from './shared.v2.types'; +import type { TTweetv2UserField } from './tweet.v2.types'; +import type { UsersV2Params, UsersV2Result, UserV2 } from './user.v2.types'; +export interface SpaceV2FieldsParams { + expansions: TypeOrArrayOf | string; + 'space.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export declare type TSpaceV2Expansion = 'invited_user_ids' | 'speaker_ids' | 'creator_id' | 'host_ids'; +export declare type TSpaceV2SpaceField = 'host_ids' | 'created_at' | 'creator_id' | 'id' | 'lang' | 'invited_user_ids' | 'participant_count' | 'speaker_ids' | 'started_at' | 'state' | 'title' | 'updated_at' | 'scheduled_start' | 'is_ticketed' | 'topic_ids' | 'ended_at' | 'subscriber_count'; +export declare type TSpaceV2State = 'live' | 'scheduled'; +export interface SpaceV2CreatorLookupParams extends SpaceV2FieldsParams { + max_results?: number; +} +export interface SpaceV2SearchParams extends Partial { + query: string; + state: TSpaceV2State; + max_results?: number; +} +export interface SpaceV2BuyersParams extends Partial { +} +declare type SpaceV2Includes = { + users?: UserV2[]; +}; +export declare type SpaceV2SingleResult = DataAndIncludeV2; +export declare type SpaceV2LookupResult = DataMetaAndIncludeV2; +export declare type SpaceV2BuyersResult = UsersV2Result; +export interface SpaceV2 { + id: string; + state: TSpaceV2State; + created_at?: string; + host_ids?: string[]; + lang?: string; + is_ticketed?: boolean; + invited_user_ids?: string[]; + participant_count?: number; + scheduled_start?: string; + speaker_ids?: string[]; + started_at?: string; + title?: string; + creator_id?: string; + updated_at?: string; + topic_ids?: string[]; + ended_at?: string; + subscriber_count?: number; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/spaces.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.d.ts new file mode 100644 index 0000000..d6d9682 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.d.ts @@ -0,0 +1,63 @@ +import { DataAndMetaV2, MetaV2, SentMeta } from './shared.v2.types'; +export interface StreamingV2GetRulesParams { + /** Comma-separated list of rule IDs. If omitted, all rules are returned. */ + ids: string; +} +export interface StreamingV2Rule { + /** Unique identifier of this rule. */ + id: string; + /** The rule text as submitted when creating the rule. */ + value: string; + /** The tag label as defined when creating the rule. */ + tag?: string; +} +export declare type StreamingV2GetRulesResult = DataAndMetaV2; +export interface StreamingV2AddRulesParams { + /** Specifies the operation you want to perform on the rules. */ + add: { + /** + * The tag label. + * This is a free-form text you can use to identify the rules that matched a specific Tweet in the streaming response. + * Tags can be the same across rules. + */ + tag?: string; + /** + * The rule text. + * If you are using a Standard Project at the Basic access level, + * you can use the basic set of operators, can submit up to 25 concurrent rules, and can submit rules up to 512 characters long. + * If you are using an Academic Research Project at the Basic access level, + * you can use all available operators, can submit up to 1,000 concurrent rules, and can submit rules up to 1,024 characters long. + */ + value: string; + }[]; +} +export interface StreamingV2DeleteRulesParams { + /** Specifies the operation you want to perform on the rules. */ + delete: { + /** Array of rule IDs, each one representing a rule already active in your stream. IDs must be submitted as strings. */ + ids: string[]; + }; +} +export declare type StreamingV2UpdateRulesParams = StreamingV2AddRulesParams | StreamingV2DeleteRulesParams; +export interface StreamingV2UpdateRulesQuery { + /** + * Set to true to test a the syntax of your rule without submitting it. + * This is useful if you want to check the syntax of a rule before removing one or more of your existing rules. + */ + dry_run: boolean; +} +export declare type StreamingV2UpdateRulesAddResult = DataAndMetaV2; +export declare type StreamingV2UpdateRulesDeleteResult = MetaV2; +export declare type StreamingV2UpdateRulesResult = StreamingV2UpdateRulesAddResult | StreamingV2UpdateRulesDeleteResult; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.js new file mode 100644 index 0000000..0a0ea9e --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/streaming.v2.types.js @@ -0,0 +1,4 @@ +// --------------- +// -- Streaming -- +// --------------- +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.d.ts new file mode 100644 index 0000000..1706be8 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.d.ts @@ -0,0 +1,205 @@ +import type { UserV2 } from './user.v2.types'; +export interface PlaceV2 { + full_name: string; + id: string; + contained_within?: string[]; + country?: string; + country_code?: string; + geo?: { + type: string; + bbox: number[]; + properties: any; + }; + name?: string; + place_type?: string; +} +export interface PlaybackCountV2 { + playback_0_count: number; + playback_25_count: number; + playback_50_count: number; + playback_75_count: number; + playback_100_count: number; +} +export declare type OrganicMetricV2 = PlaybackCountV2 & { + view_count: number; +}; +export interface MediaVariantsV2 { + bit_rate?: number; + content_type: 'video/mp4' | 'application/x-mpegURL' | string; + url: string; +} +export interface MediaObjectV2 { + media_key: string; + type: 'video' | 'animated_gif' | 'photo' | string; + duration_ms?: number; + height?: number; + width?: number; + url?: string; + preview_image_url?: string; + alt_text?: string; + non_public_metrics?: PlaybackCountV2; + organic_metrics?: OrganicMetricV2; + promoted_metrics?: OrganicMetricV2; + public_metrics?: { + view_count: number; + }; + variants?: MediaVariantsV2[]; +} +export interface PollV2 { + id: string; + options: { + position: number; + label: string; + votes: number; + }[]; + duration_minutes?: number; + end_datetime?: string; + voting_status?: string; +} +export interface ReferencedTweetV2 { + type: 'retweeted' | 'quoted' | 'replied_to'; + id: string; +} +export interface TweetAttachmentV2 { + media_keys?: string[]; + poll_ids?: string[]; +} +export interface TweetGeoV2 { + coordinates: { + type: string; + coordinates: [number, number] | null; + }; + place_id: string; +} +interface TweetContextAnnotationItemV2 { + id: string; + name: string; + description?: string; +} +export declare type TweetContextAnnotationDomainV2 = TweetContextAnnotationItemV2; +export declare type TweetContextAnnotationEntityV2 = TweetContextAnnotationItemV2; +export interface TweetContextAnnotationV2 { + domain: TweetContextAnnotationDomainV2; + entity: TweetContextAnnotationEntityV2; +} +export interface TweetEntityAnnotationsV2 { + start: number; + end: number; + probability: number; + type: string; + normalized_text: string; +} +export interface TweetEntityUrlV2 { + start: number; + end: number; + url: string; + expanded_url: string; + display_url: string; + unwound_url: string; + title?: string; + description?: string; + status?: string; + images?: TweetEntityUrlImageV2[]; +} +export interface TweetEntityUrlImageV2 { + url: string; + width: number; + height: number; +} +export interface TweetEntityHashtagV2 { + start: number; + end: number; + tag: string; +} +export interface TweetEntityMentionV2 { + start: number; + end: number; + username: string; + id: string; +} +export interface TweetEntitiesV2 { + annotations: TweetEntityAnnotationsV2[]; + urls: TweetEntityUrlV2[]; + hashtags: TweetEntityHashtagV2[]; + cashtags: TweetEntityHashtagV2[]; + mentions: TweetEntityMentionV2[]; +} +export interface TweetWithheldInfoV2 { + copyright: boolean; + country_codes: string[]; + scope: 'tweet' | 'user'; +} +export interface TweetPublicMetricsV2 { + retweet_count: number; + reply_count: number; + like_count: number; + quote_count: number; + impression_count: number; +} +export interface TweetNonPublicMetricsV2 { + impression_count: number; + url_link_clicks: number; +} +export interface TweetOrganicMetricsV2 { + impression_count: number; + url_link_clicks: number; + user_profile_clicks: number; + retweet_count: number; + reply_count: number; + like_count: number; +} +export declare type TweetPromotedMetricsV2 = TweetOrganicMetricsV2; +export declare type TTweetReplySettingsV2 = 'mentionedUsers' | 'following' | 'everyone'; +export interface SendTweetV2Params { + direct_message_deep_link?: string; + for_super_followers_only?: 'True' | 'False'; + geo?: { + place_id: string; + }; + media?: { + media_ids?: string[]; + tagged_user_ids?: string[]; + }; + poll?: { + duration_minutes: number; + options: string[]; + }; + quote_tweet_id?: string; + reply?: { + exclude_reply_user_ids?: string[]; + in_reply_to_tweet_id: string; + }; + reply_settings?: TTweetReplySettingsV2 | string; + text?: string; +} +export interface TweetV2 { + id: string; + text: string; + edit_history_tweet_ids: string[]; + created_at?: string; + author_id?: string; + conversation_id?: string; + in_reply_to_user_id?: string; + referenced_tweets?: ReferencedTweetV2[]; + attachments?: TweetAttachmentV2; + geo?: TweetGeoV2; + context_annotations?: TweetContextAnnotationV2[]; + entities?: TweetEntitiesV2; + withheld?: TweetWithheldInfoV2; + public_metrics?: TweetPublicMetricsV2; + non_public_metrics?: TweetNonPublicMetricsV2; + organic_metrics?: TweetOrganicMetricsV2; + promoted_metrics?: TweetPromotedMetricsV2; + possibly_sensitive?: boolean; + lang?: string; + reply_settings?: 'everyone' | 'mentionedUsers' | 'following'; + source?: string; +} +export interface ApiV2Includes { + tweets?: TweetV2[]; + users?: UserV2[]; + places?: PlaceV2[]; + media?: MediaObjectV2[]; + polls?: PollV2[]; +} +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.js b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.definition.v2.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.d.ts new file mode 100644 index 0000000..f87064b --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.d.ts @@ -0,0 +1,143 @@ +/// +import type { TweetV2, ApiV2Includes } from './tweet.definition.v2'; +import type { TypeOrArrayOf } from '../shared.types'; +import type { DataAndIncludeV2, DataAndMetaV2, DataMetaAndIncludeV2, DataV2, MetaV2 } from './shared.v2.types'; +import { UserV2 } from './user.v2.types'; +import { PaginableCountMetaV2 } from './shared.v2.types'; +export interface TweetV2TimelineParams extends Partial { + /** ISO date string */ + end_time?: string; + /** ISO date string */ + start_time?: string; + max_results?: number; + since_id?: string; + until_id?: string; + next_token?: string; +} +export interface Tweetv2SearchParams extends TweetV2TimelineParams { + previous_token?: string; + query: string; + sort_order?: 'recency' | 'relevancy'; +} +export interface TweetV2PaginableTimelineParams extends TweetV2TimelineParams { + pagination_token?: string; +} +export interface TweetV2PaginableListParams extends Partial { + pagination_token?: string; + max_results?: number; +} +export interface TweetV2UserTimelineParams extends TweetV2PaginableTimelineParams { + exclude?: TypeOrArrayOf<'retweets' | 'replies'>; +} +export interface TweetV2HomeTimelineParams extends TweetV2UserTimelineParams { +} +export declare type TTweetv2Expansion = 'attachments.poll_ids' | 'attachments.media_keys' | 'author_id' | 'referenced_tweets.id' | 'in_reply_to_user_id' | 'edit_history_tweet_ids' | 'geo.place_id' | 'entities.mentions.username' | 'referenced_tweets.id.author_id'; +export declare type TTweetv2MediaField = 'duration_ms' | 'height' | 'media_key' | 'preview_image_url' | 'type' | 'url' | 'width' | 'public_metrics' | 'non_public_metrics' | 'organic_metrics' | 'alt_text' | 'variants'; +export declare type TTweetv2PlaceField = 'contained_within' | 'country' | 'country_code' | 'full_name' | 'geo' | 'id' | 'name' | 'place_type'; +export declare type TTweetv2PollField = 'duration_minutes' | 'end_datetime' | 'id' | 'options' | 'voting_status'; +export declare type TTweetv2TweetField = 'attachments' | 'author_id' | 'context_annotations' | 'conversation_id' | 'created_at' | 'entities' | 'geo' | 'id' | 'in_reply_to_user_id' | 'lang' | 'public_metrics' | 'non_public_metrics' | 'promoted_metrics' | 'organic_metrics' | 'edit_controls' | 'possibly_sensitive' | 'referenced_tweets' | 'reply_settings' | 'source' | 'text' | 'withheld'; +export declare type TTweetv2UserField = 'created_at' | 'description' | 'entities' | 'id' | 'location' | 'name' | 'pinned_tweet_id' | 'profile_image_url' | 'protected' | 'public_metrics' | 'url' | 'username' | 'verified' | 'verified_type' | 'withheld'; +export interface Tweetv2FieldsParams { + expansions: TypeOrArrayOf | string; + 'media.fields': TypeOrArrayOf | string; + 'place.fields': TypeOrArrayOf | string; + 'poll.fields': TypeOrArrayOf | string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface TweetSearchV2StreamParams extends Tweetv2FieldsParams { + backfill_minutes: number; +} +export interface TweetV2CountParams { + query: string; + end_time?: string; + start_time?: string; + until_id?: string; + since_id?: string; + granularity?: 'day' | 'hour' | 'minute'; +} +export interface TweetV2CountAllParams extends TweetV2CountParams { + next_token: string; +} +export declare type TweetV2CountResult = DataAndMetaV2<{ + start: string; + end: string; + tweet_count: number; +}[], { + total_tweet_count: number; +}>; +export declare type TweetV2CountAllResult = TweetV2CountResult & MetaV2<{ + next_token: string; +}>; +export declare type Tweetv2TimelineResult = DataMetaAndIncludeV2; +export declare type Tweetv2ListResult = DataMetaAndIncludeV2; +export declare type Tweetv2SearchResult = Tweetv2TimelineResult; +export declare type TweetV2PaginableTimelineResult = Tweetv2TimelineResult & MetaV2<{ + previous_token?: string; +}>; +export declare type TweetV2UserTimelineResult = TweetV2PaginableTimelineResult; +export declare type TweetV2HomeTimelineResult = TweetV2PaginableTimelineResult; +export declare type TweetV2LookupResult = DataAndIncludeV2; +export declare type TweetV2SingleResult = DataAndIncludeV2; +export declare type TweetV2SingleStreamResult = TweetV2SingleResult & { + matching_rules: { + id: string | number; + tag: string; + }[]; +}; +export declare type TweetV2PostTweetResult = DataV2<{ + id: string; + text: string; +}>; +export declare type TweetV2HideReplyResult = DataV2<{ + hidden: boolean; +}>; +export declare type TweetV2LikeResult = DataV2<{ + liked: boolean; +}>; +export declare type TweetV2LikedByResult = DataMetaAndIncludeV2; +export declare type TweetV2RetweetResult = DataV2<{ + retweeted: boolean; +}>; +export declare type TweetV2RetweetedByResult = TweetV2LikedByResult; +export declare type TweetV2BookmarkResult = DataV2<{ + bookmarked: boolean; +}>; +export declare type TweetV2DeleteTweetResult = DataV2<{ + deleted: boolean; +}>; +export interface BatchComplianceJobV2 { + resumable: false; + type: 'tweets' | 'users'; + download_expires_at: string; + created_at: string; + upload_url: string; + download_url: string; + id: string; + status: 'created' | 'complete' | 'in_progress' | 'expired' | 'failed'; + upload_expires_at: string; + error?: string; +} +export interface BatchComplianceSearchV2Params { + type: 'tweets' | 'users'; + status?: 'created' | 'complete' | 'in_progress' | 'expired' | 'failed'; +} +export interface BatchComplianceV2Params { + type: 'tweets' | 'users'; + name?: string; + ids: string[] | Buffer; +} +export interface BatchComplianceV2JobResult { + id: string; + action: 'delete'; + created_at: string; + redacted_at?: string; + reason: 'deleted' | 'suspended' | 'protected' | 'scrub_geo' | 'deactivated'; +} +export declare type BatchComplianceListV2Result = DataV2; +export declare type BatchComplianceV2Result = DataV2; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/tweet.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.d.ts b/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.d.ts new file mode 100644 index 0000000..115b3af --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.d.ts @@ -0,0 +1,96 @@ +import type { CashtagEntity, HashtagEntity, MentionEntity, UrlEntity } from '../entities.types'; +import type { ApiV2Includes } from './tweet.definition.v2'; +import type { DataAndIncludeV2, DataMetaAndIncludeV2, DataV2 } from './shared.v2.types'; +import type { TTweetv2MediaField, TTweetv2PlaceField, TTweetv2PollField, TTweetv2TweetField, TTweetv2UserField } from './tweet.v2.types'; +import type { TypeOrArrayOf } from '../shared.types'; +import { PaginableCountMetaV2 } from './shared.v2.types'; +export declare type TUserV2Expansion = 'pinned_tweet_id'; +export interface UsersV2Params { + expansions: TypeOrArrayOf; + 'media.fields': TypeOrArrayOf | string; + 'place.fields': TypeOrArrayOf | string; + 'poll.fields': TypeOrArrayOf | string; + 'tweet.fields': TypeOrArrayOf | string; + 'user.fields': TypeOrArrayOf | string; +} +export interface UserV2TimelineParams { + expansions?: TypeOrArrayOf; + 'media.fields'?: TypeOrArrayOf | string; + 'place.fields'?: TypeOrArrayOf | string; + 'poll.fields'?: TypeOrArrayOf | string; + 'tweet.fields'?: TypeOrArrayOf | string; + 'user.fields'?: TypeOrArrayOf | string; + max_results?: number; + pagination_token?: string; +} +export interface TweetRetweetedOrLikedByV2Params extends Partial { + asPaginator?: boolean; +} +export interface TweetRetweetedOrLikedByV2ParamsWithoutPaginator extends TweetRetweetedOrLikedByV2Params { + asPaginator?: false; +} +export interface TweetRetweetedOrLikedByV2ParamsWithPaginator extends TweetRetweetedOrLikedByV2Params { + asPaginator: true; +} +export interface FollowersV2Params extends UserV2TimelineParams { + asPaginator?: boolean; +} +export interface FollowersV2ParamsWithoutPaginator extends FollowersV2Params { + asPaginator?: false; +} +export interface FollowersV2ParamsWithPaginator extends FollowersV2Params { + asPaginator: true; +} +export declare type UserV2Result = DataAndIncludeV2; +export declare type UsersV2Result = DataAndIncludeV2; +export declare type UserV2FollowResult = DataV2<{ + following: boolean; + pending_follow: boolean; +}>; +export declare type UserV2UnfollowResult = DataV2<{ + following: boolean; +}>; +export declare type UserV2BlockResult = DataV2<{ + blocking: boolean; +}>; +export declare type UserV2MuteResult = DataV2<{ + muting: boolean; +}>; +export declare type UserV2TimelineResult = DataMetaAndIncludeV2; +/** @deprecated Use {UserV2TimelineResult} instead. */ +export declare type FollowersV2Result = UserV2TimelineResult; +export interface UserV2 { + id: string; + name: string; + username: string; + created_at?: string; + protected?: boolean; + withheld?: { + country_codes?: string[]; + scope?: 'user'; + }; + location?: string; + url?: string; + description?: string; + verified?: boolean; + verified_type?: "none" | "blue" | "business" | "government"; + entities?: { + url?: { + urls: UrlEntity[]; + }; + description: { + urls?: UrlEntity[]; + hashtags?: HashtagEntity[]; + cashtags?: CashtagEntity[]; + mentions?: MentionEntity[]; + }; + }; + profile_image_url?: string; + public_metrics?: { + followers_count?: number; + following_count?: number; + tweet_count?: number; + listed_count?: number; + }; + pinned_tweet_id?: string; +} diff --git a/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.js b/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/types/v2/user.v2.types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.d.ts new file mode 100644 index 0000000..38acc60 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.d.ts @@ -0,0 +1,109 @@ +/// +import { DmEventsV1Paginator, WelcomeDmV1Paginator } from '../paginators/dm.paginator.v1'; +import { SendDMV1Params, DirectMessageCreateV1Result, ReceivedDMEventV1, GetDmListV1Args, MessageCreateDataV1, WelcomeDirectMessageCreateV1Result, WelcomeDmRuleV1Result, WelcomeDmRuleListV1Result, DirectMessageCreateV1 } from '../types'; +import TwitterApiv1ReadWrite from './client.v1.write'; +/** + * Twitter v1.1 API client with read/write/DMs rights. + */ +export declare class TwitterApiv1 extends TwitterApiv1ReadWrite { + protected _prefix: string; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv1ReadWrite; + /** + * Publishes a new message_create event resulting in a Direct Message sent to a specified user from the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event + */ + sendDm({ recipient_id, custom_profile_id, ...params }: SendDMV1Params): Promise; + /** + * Returns a single Direct Message event by the given id. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/get-event + */ + getDmEvent(id: string): Promise; + /** + * Deletes the direct message specified in the required ID parameter. + * The authenticating user must be the recipient of the specified direct message. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/delete-message-event + */ + deleteDm(id: string): Promise; + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + listDmEvents(args?: Partial): Promise; + /** + * Creates a new Welcome Message that will be stored and sent in the future from the authenticating user in defined circumstances. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message + */ + newWelcomeDm(name: string, data: MessageCreateDataV1): Promise; + /** + * Returns a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message + */ + getWelcomeDm(id: string): Promise; + /** + * Deletes a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message + */ + deleteWelcomeDm(id: string): Promise; + /** + * Updates a Welcome Message by the given ID. + * Updates to the welcome_message object are atomic. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/update-welcome-message + */ + updateWelcomeDm(id: string, data: MessageCreateDataV1): Promise; + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + listWelcomeDms(args?: Partial): Promise; + /** + * Creates a new Welcome Message Rule that determines which Welcome Message will be shown in a given conversation. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message-rule + */ + newWelcomeDmRule(welcomeMessageId: string): Promise; + /** + * Returns a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message-rule + */ + getWelcomeDmRule(id: string): Promise; + /** + * Deletes a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule + */ + deleteWelcomeDmRule(id: string): Promise; + /** + * Retrieves all welcome DM rules for this account. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/list-welcome-message-rules + */ + listWelcomeDmRules(args?: Partial): Promise; + /** + * Set the current showed welcome message for logged account ; wrapper for Welcome DM rules. + * Test if a rule already exists, delete if any, then create a rule for current message ID. + * + * If you don't have already a welcome message, create it with `.newWelcomeMessage`. + */ + setWelcomeDm(welcomeMessageId: string, deleteAssociatedWelcomeDmWhenDeletingRule?: boolean): Promise; + /** + * Marks a message as read in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-read-receipt + */ + markDmAsRead(lastEventId: string, recipientId: string): Promise; + /** + * Displays a visual typing indicator in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-typing-indicator + */ + indicateDmTyping(recipientId: string): Promise; + /** + * Get a single image attached to a direct message. TwitterApi client must be logged with OAuth 1.0a. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/message-attachments/guides/retrieving-media + */ + downloadDmImage(urlOrDm: string | DirectMessageCreateV1): Promise; +} +export default TwitterApiv1; diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.js b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.js new file mode 100644 index 0000000..41b6916 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.js @@ -0,0 +1,225 @@ +import { API_V1_1_PREFIX } from '../globals'; +import { DmEventsV1Paginator, WelcomeDmV1Paginator } from '../paginators/dm.paginator.v1'; +import { EDirectMessageEventTypeV1, } from '../types'; +import TwitterApiv1ReadWrite from './client.v1.write'; +/** + * Twitter v1.1 API client with read/write/DMs rights. + */ +export class TwitterApiv1 extends TwitterApiv1ReadWrite { + constructor() { + super(...arguments); + this._prefix = API_V1_1_PREFIX; + } + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } + /* Direct messages */ + // Part: Sending and receiving events + /** + * Publishes a new message_create event resulting in a Direct Message sent to a specified user from the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event + */ + sendDm({ recipient_id, custom_profile_id, ...params }) { + const args = { + event: { + type: EDirectMessageEventTypeV1.Create, + [EDirectMessageEventTypeV1.Create]: { + target: { recipient_id }, + message_data: params, + }, + }, + }; + if (custom_profile_id) { + args.event[EDirectMessageEventTypeV1.Create].custom_profile_id = custom_profile_id; + } + return this.post('direct_messages/events/new.json', args, { + forceBodyMode: 'json', + }); + } + /** + * Returns a single Direct Message event by the given id. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/get-event + */ + getDmEvent(id) { + return this.get('direct_messages/events/show.json', { id }); + } + /** + * Deletes the direct message specified in the required ID parameter. + * The authenticating user must be the recipient of the specified direct message. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/delete-message-event + */ + deleteDm(id) { + return this.delete('direct_messages/events/destroy.json', { id }); + } + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + async listDmEvents(args = {}) { + const queryParams = { ...args }; + const initialRq = await this.get('direct_messages/events/list.json', queryParams, { fullResponse: true }); + return new DmEventsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + // Part: Welcome messages (events) + /** + * Creates a new Welcome Message that will be stored and sent in the future from the authenticating user in defined circumstances. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message + */ + newWelcomeDm(name, data) { + const args = { + [EDirectMessageEventTypeV1.WelcomeCreate]: { + name, + message_data: data, + }, + }; + return this.post('direct_messages/welcome_messages/new.json', args, { + forceBodyMode: 'json', + }); + } + /** + * Returns a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message + */ + getWelcomeDm(id) { + return this.get('direct_messages/welcome_messages/show.json', { id }); + } + /** + * Deletes a Welcome Message by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message + */ + deleteWelcomeDm(id) { + return this.delete('direct_messages/welcome_messages/destroy.json', { id }); + } + /** + * Updates a Welcome Message by the given ID. + * Updates to the welcome_message object are atomic. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/update-welcome-message + */ + updateWelcomeDm(id, data) { + const args = { message_data: data }; + return this.put('direct_messages/welcome_messages/update.json', args, { + forceBodyMode: 'json', + query: { id }, + }); + } + /** + * Returns all Direct Message events (both sent and received) within the last 30 days. + * Sorted in reverse-chronological order. + * + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + */ + async listWelcomeDms(args = {}) { + const queryParams = { ...args }; + const initialRq = await this.get('direct_messages/welcome_messages/list.json', queryParams, { fullResponse: true }); + return new WelcomeDmV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + // Part: Welcome message (rules) + /** + * Creates a new Welcome Message Rule that determines which Welcome Message will be shown in a given conversation. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/new-welcome-message-rule + */ + newWelcomeDmRule(welcomeMessageId) { + return this.post('direct_messages/welcome_messages/rules/new.json', { + welcome_message_rule: { welcome_message_id: welcomeMessageId }, + }, { + forceBodyMode: 'json', + }); + } + /** + * Returns a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/get-welcome-message-rule + */ + getWelcomeDmRule(id) { + return this.get('direct_messages/welcome_messages/rules/show.json', { id }); + } + /** + * Deletes a Welcome Message Rule by the given id. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule + */ + deleteWelcomeDmRule(id) { + return this.delete('direct_messages/welcome_messages/rules/destroy.json', { id }); + } + /** + * Retrieves all welcome DM rules for this account. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/welcome-messages/api-reference/list-welcome-message-rules + */ + async listWelcomeDmRules(args = {}) { + const queryParams = { ...args }; + return this.get('direct_messages/welcome_messages/rules/list.json', queryParams); + } + /** + * Set the current showed welcome message for logged account ; wrapper for Welcome DM rules. + * Test if a rule already exists, delete if any, then create a rule for current message ID. + * + * If you don't have already a welcome message, create it with `.newWelcomeMessage`. + */ + async setWelcomeDm(welcomeMessageId, deleteAssociatedWelcomeDmWhenDeletingRule = true) { + var _a; + const existingRules = await this.listWelcomeDmRules(); + if ((_a = existingRules.welcome_message_rules) === null || _a === void 0 ? void 0 : _a.length) { + for (const rule of existingRules.welcome_message_rules) { + await this.deleteWelcomeDmRule(rule.id); + if (deleteAssociatedWelcomeDmWhenDeletingRule) { + await this.deleteWelcomeDm(rule.welcome_message_id); + } + } + } + return this.newWelcomeDmRule(welcomeMessageId); + } + // Part: Read indicator + /** + * Marks a message as read in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-read-receipt + */ + markDmAsRead(lastEventId, recipientId) { + return this.post('direct_messages/mark_read.json', { + last_read_event_id: lastEventId, + recipient_id: recipientId, + }, { forceBodyMode: 'url' }); + } + /** + * Displays a visual typing indicator in the recipient’s Direct Message conversation view with the sender. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/typing-indicator-and-read-receipts/api-reference/new-typing-indicator + */ + indicateDmTyping(recipientId) { + return this.post('direct_messages/indicate_typing.json', { + recipient_id: recipientId, + }, { forceBodyMode: 'url' }); + } + // Part: Images + /** + * Get a single image attached to a direct message. TwitterApi client must be logged with OAuth 1.0a. + * https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/message-attachments/guides/retrieving-media + */ + async downloadDmImage(urlOrDm) { + if (typeof urlOrDm !== 'string') { + const attachment = urlOrDm[EDirectMessageEventTypeV1.Create].message_data.attachment; + if (!attachment) { + throw new Error('The given direct message doesn\'t contain any attachment'); + } + urlOrDm = attachment.media.media_url_https; + } + const data = await this.get(urlOrDm, undefined, { forceParseMode: 'buffer', prefix: '' }); + if (!data.length) { + throw new Error('Image not found. Make sure you are logged with credentials able to access direct messages, and check the URL.'); + } + return data; + } +} +export default TwitterApiv1; diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.d.ts b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.d.ts new file mode 100644 index 0000000..b4f69c5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.d.ts @@ -0,0 +1,297 @@ +import TwitterApiSubClient from '../client.subclient'; +import { FilterStreamV1Params, SampleStreamV1Params, UserV1, VerifyCredentialsV1Params, AppRateLimitV1Result, TAppRateLimitResourceV1, HelpLanguageV1Result, ReverseGeoCodeV1Params, ReverseGeoCodeV1Result, PlaceV1, SearchGeoV1Params, SearchGeoV1Result, TrendMatchV1, TrendsPlaceV1Params, TrendLocationV1, TweetV1TimelineParams, TweetV1UserTimelineParams, TweetV1, MediaStatusV1Result, OembedTweetV1Params, OembedTweetV1Result, MuteUserListV1Params, MuteUserIdsV1Params, UserFollowerIdsV1Params, UserFollowingsIdsV1Params, UserFriendListV1Params, UserFollowerListV1Params, UserSearchV1Params, AccountSettingsV1, ProfileBannerSizeV1, ProfileBannerSizeV1Params, FriendshipLookupV1Params, FriendshipLookupV1, FriendshipShowV1Params, FriendshipV1, FriendshipsIncomingV1Params, UserShowV1Params, UserLookupV1Params, TweetShowV1Params, TweetLookupNoMapV1Params, TweetLookupMapV1Params, TweetLookupMapV1Result, ListListsV1Params, ListV1, ListMembersV1Params, ListMemberShowV1Params, ListMembershipsV1Params, ListOwnershipsV1Params, GetListV1Params, ListStatusesV1Params, ListSubscriptionsV1Params } from '../types'; +import { HomeTimelineV1Paginator, ListTimelineV1Paginator, MentionTimelineV1Paginator, UserFavoritesV1Paginator, UserTimelineV1Paginator } from '../paginators/tweet.paginator.v1'; +import { MuteUserIdsV1Paginator, MuteUserListV1Paginator } from '../paginators/mutes.paginator.v1'; +import { UserFollowerIdsV1Paginator, UserFollowerListV1Paginator } from '../paginators/followers.paginator.v1'; +import { UserFollowersIdsV1Paginator, UserFriendListV1Paginator } from '../paginators/friends.paginator.v1'; +import { FriendshipsIncomingV1Paginator, FriendshipsOutgoingV1Paginator, UserSearchV1Paginator } from '../paginators/user.paginator.v1'; +import { ListMembershipsV1Paginator, ListMembersV1Paginator, ListOwnershipsV1Paginator, ListSubscribersV1Paginator, ListSubscriptionsV1Paginator } from '../paginators/list.paginator.v1'; +import TweetStream from '../stream/TweetStream'; +import { PromiseOrType } from '../types/shared.types'; +/** + * Base Twitter v1 client with only read right. + */ +export default class TwitterApiv1ReadOnly extends TwitterApiSubClient { + protected _prefix: string; + /** + * Returns a single Tweet, specified by the id parameter. The Tweet's author will also be embedded within the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id + */ + singleTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns fully-hydrated Tweet objects for up to 100 Tweets per request. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-lookup + */ + tweets(ids: string | string[], options?: TweetLookupNoMapV1Params): Promise; + tweets(ids: string | string[], options: TweetLookupMapV1Params): Promise; + /** + * Returns a single Tweet, specified by either a Tweet web URL or the Tweet ID, in an oEmbed-compatible format. + * The returned HTML snippet will be automatically recognized as an Embedded Tweet when Twitter's widget JavaScript is included on the page. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-oembed + */ + oembedTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets and Retweets posted by the authenticating user and the users they follow. + * The home timeline is central to how most users interact with the Twitter service. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-home_timeline + */ + homeTimeline(options?: Partial): Promise; + /** + * Returns the 20 most recent mentions (Tweets containing a users's @screen_name) for the authenticating user. + * The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-mentions_timeline + */ + mentionTimeline(options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the user_id parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + userTimeline(userId: string, options?: Partial): Promise; + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the screen_name parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + userTimelineByUsername(username: string, options?: Partial): Promise; + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + favoriteTimeline(userId: string, options?: Partial): Promise; + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + favoriteTimelineByUsername(username: string, options?: Partial): Promise; + /** + * Returns a variety of information about the user specified by the required user_id or screen_name parameter. + * The author's most recent Tweet will be returned inline when possible. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-show + */ + user(user: UserShowV1Params): Promise; + /** + * Returns fully-hydrated user objects for up to 100 users per request, + * as specified by comma-separated values passed to the user_id and/or screen_name parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup + */ + users(query: UserLookupV1Params): Promise; + /** + * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; + * returns a 401 status code and an error message if not. + * Use this method to test if supplied user credentials are valid. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials + */ + verifyCredentials(options?: Partial): Promise; + /** + * Returns an array of user objects the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list + */ + listMutedUsers(options?: Partial): Promise; + /** + * Returns an array of numeric user ids the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids + */ + listMutedUserIds(options?: Partial): Promise; + /** + * Returns an array of user objects of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-list + */ + userFriendList(options?: Partial): Promise; + /** + * Returns an array of user objects of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-list + */ + userFollowerList(options?: Partial): Promise; + /** + * Returns an array of numeric user ids of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids + */ + userFollowerIds(options?: Partial): Promise; + /** + * Returns an array of numeric user ids of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids + */ + userFollowingIds(options?: Partial): Promise; + /** + * Provides a simple, relevance-based search interface to public user accounts on Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search + */ + searchUsers(query: string, options?: Partial): Promise; + /** + * Returns detailed information about the relationship between two arbitrary users. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show + */ + friendship(sources: FriendshipShowV1Params): Promise; + /** + * Returns the relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup + */ + friendships(friendships: FriendshipLookupV1Params): Promise; + /** + * Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids + */ + friendshipsNoRetweets(): Promise; + /** + * Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming + */ + friendshipsIncoming(options?: Partial): Promise; + /** + * Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing + */ + friendshipsOutgoing(options?: Partial): Promise; + /** + * Get current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + accountSettings(): Promise; + /** + * Returns a map of the available size variations of the specified user's profile banner. + * If the user has not uploaded a profile banner, a HTTP 404 will be served instead. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-users-profile_banner + */ + userProfileBannerSizes(params: ProfileBannerSizeV1Params): Promise; + /** + * Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-show + */ + list(options: GetListV1Params): Promise; + /** + * Returns all lists the authenticating or specified user subscribes to, including their own. + * If no user is given, the authenticating user is used. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-list + */ + lists(options?: ListListsV1Params): Promise; + /** + * Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members + */ + listMembers(options?: Partial): Promise; + /** + * Check if the specified user is a member of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show + */ + listGetMember(options: ListMemberShowV1Params): Promise; + /** + * Returns the lists the specified user has been added to. + * If user_id or screen_name are not provided, the memberships for the authenticating user are returned. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships + */ + listMemberships(options?: Partial): Promise; + /** + * Returns the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships + */ + listOwnerships(options?: Partial): Promise; + /** + * Returns a timeline of tweets authored by members of the specified list. Retweets are included by default. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses + */ + listStatuses(options: Partial): Promise; + /** + * Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers + */ + listSubscribers(options?: Partial): Promise; + /** + * Check if the specified user is a subscriber of the specified list. Returns the user if they are a subscriber. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show + */ + listGetSubscriber(options: ListMemberShowV1Params): Promise; + /** + * Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. + * Does not include the user's own lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions + */ + listSubscriptions(options?: Partial): Promise; + /** + * The STATUS command (this method) is used to periodically poll for updates of media processing operation. + * After the STATUS command response returns succeeded, you can move on to the next step which is usually create Tweet with media_id. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/get-media-upload-status + */ + mediaInfo(mediaId: string): Promise; + /** + * Returns public statuses that match one or more filter predicates. + * Multiple parameters may be specified which allows most clients to use a single connection to the Streaming API. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/api-reference/post-statuses-filter + */ + filterStream(params?: Partial & { + autoConnect?: true; + }): Promise>; + filterStream(params: Partial & { + autoConnect: false; + }): TweetStream; + filterStream(params?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Returns a small random sample of all public statuses. + * The Tweets returned by the default access level are the same, so if two different clients connect to this endpoint, they will see the same Tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/sample-realtime/api-reference/get-statuses-sample + */ + sampleStream(params?: Partial & { + autoConnect?: true; + }): Promise>; + sampleStream(params: Partial & { + autoConnect: false; + }): TweetStream; + sampleStream(params?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Create a client that is prefixed with `https//stream.twitter.com` instead of classic API URL. + */ + get stream(): this; + /** + * Returns the top 50 trending topics for a specific id, if trending information is available for it. + * Note: The id parameter for this endpoint is the "where on earth identifier" or WOEID, which is a legacy identifier created by Yahoo and has been deprecated. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/trends-for-location/api-reference/get-trends-place + */ + trendsByPlace(woeId: string | number, options?: Partial): Promise; + /** + * Returns the locations that Twitter has trending topic information for. + * The response is an array of "locations" that encode the location's WOEID + * and some other human-readable information such as a canonical name and country the location belongs in. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-available + */ + trendsAvailable(): Promise; + /** + * Returns the locations that Twitter has trending topic information for, closest to a specified location. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-closest + */ + trendsClosest(lat: number, long: number): Promise; + /** + * Returns all the information about a known place. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/place-information/api-reference/get-geo-id-place_id + */ + geoPlace(placeId: string): Promise; + /** + * Search for places that can be attached to a Tweet via POST statuses/update. + * This request will return a list of all the valid places that can be used as the place_id when updating a status. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-search + */ + geoSearch(options: Partial): Promise; + /** + * Given a latitude and a longitude, searches for up to 20 places that can be used as a place_id when updating a status. + * This request is an informative call and will deliver generalized results about geography. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-reverse_geocode + */ + geoReverseGeoCode(options: ReverseGeoCodeV1Params): Promise; + /** + * Returns the current rate limits for methods belonging to the specified resource families. + * Each API resource belongs to a "resource family" which is indicated in its method documentation. + * The method's resource family can be determined from the first component of the path after the resource version. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status + */ + rateLimitStatuses(...resources: TAppRateLimitResourceV1[]): Promise; + /** + * Returns the list of languages supported by Twitter along with the language code supported by Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/supported-languages/api-reference/get-help-languages + */ + supportedLanguages(): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.js b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.js new file mode 100644 index 0000000..8ca965d --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.read.js @@ -0,0 +1,612 @@ +import TwitterApiSubClient from '../client.subclient'; +import { API_V1_1_PREFIX, API_V1_1_STREAM_PREFIX, API_V1_1_UPLOAD_PREFIX } from '../globals'; +import { arrayWrap } from '../helpers'; +import TwitterApiv1 from '../v1/client.v1'; +import { HomeTimelineV1Paginator, ListTimelineV1Paginator, MentionTimelineV1Paginator, UserFavoritesV1Paginator, UserTimelineV1Paginator } from '../paginators/tweet.paginator.v1'; +import { MuteUserIdsV1Paginator, MuteUserListV1Paginator } from '../paginators/mutes.paginator.v1'; +import { UserFollowerIdsV1Paginator, UserFollowerListV1Paginator } from '../paginators/followers.paginator.v1'; +import { UserFollowersIdsV1Paginator, UserFriendListV1Paginator } from '../paginators/friends.paginator.v1'; +import { FriendshipsIncomingV1Paginator, FriendshipsOutgoingV1Paginator, UserSearchV1Paginator } from '../paginators/user.paginator.v1'; +import { ListMembershipsV1Paginator, ListMembersV1Paginator, ListOwnershipsV1Paginator, ListSubscribersV1Paginator, ListSubscriptionsV1Paginator } from '../paginators/list.paginator.v1'; +/** + * Base Twitter v1 client with only read right. + */ +export default class TwitterApiv1ReadOnly extends TwitterApiSubClient { + constructor() { + super(...arguments); + this._prefix = API_V1_1_PREFIX; + } + /* Tweets */ + /** + * Returns a single Tweet, specified by the id parameter. The Tweet's author will also be embedded within the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id + */ + singleTweet(tweetId, options = {}) { + return this.get('statuses/show.json', { tweet_mode: 'extended', id: tweetId, ...options }); + } + tweets(ids, options = {}) { + return this.post('statuses/lookup.json', { tweet_mode: 'extended', id: ids, ...options }); + } + /** + * Returns a single Tweet, specified by either a Tweet web URL or the Tweet ID, in an oEmbed-compatible format. + * The returned HTML snippet will be automatically recognized as an Embedded Tweet when Twitter's widget JavaScript is included on the page. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-oembed + */ + oembedTweet(tweetId, options = {}) { + return this.get('oembed', { + url: `https://twitter.com/i/statuses/${tweetId}`, + ...options, + }, { prefix: 'https://publish.twitter.com/' }); + } + /* Tweets timelines */ + /** + * Returns a collection of the most recent Tweets and Retweets posted by the authenticating user and the users they follow. + * The home timeline is central to how most users interact with the Twitter service. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-home_timeline + */ + async homeTimeline(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('statuses/home_timeline.json', queryParams, { fullResponse: true }); + return new HomeTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the 20 most recent mentions (Tweets containing a users's @screen_name) for the authenticating user. + * The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-mentions_timeline + */ + async mentionTimeline(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('statuses/mentions_timeline.json', queryParams, { fullResponse: true }); + return new MentionTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the user_id parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + async userTimeline(userId, options = {}) { + const queryParams = { + tweet_mode: 'extended', + user_id: userId, + ...options, + }; + const initialRq = await this.get('statuses/user_timeline.json', queryParams, { fullResponse: true }); + return new UserTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of the most recent Tweets posted by the user indicated by the screen_name parameters. + * User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline + */ + async userTimelineByUsername(username, options = {}) { + const queryParams = { + tweet_mode: 'extended', + screen_name: username, + ...options, + }; + const initialRq = await this.get('statuses/user_timeline.json', queryParams, { fullResponse: true }); + return new UserTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + async favoriteTimeline(userId, options = {}) { + const queryParams = { + tweet_mode: 'extended', + user_id: userId, + ...options, + }; + const initialRq = await this.get('favorites/list.json', queryParams, { fullResponse: true }); + return new UserFavoritesV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the most recent Tweets liked by the authenticating or specified user, 20 tweets by default. + * Note: favorites are now known as likes. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list + */ + async favoriteTimelineByUsername(username, options = {}) { + const queryParams = { + tweet_mode: 'extended', + screen_name: username, + ...options, + }; + const initialRq = await this.get('favorites/list.json', queryParams, { fullResponse: true }); + return new UserFavoritesV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Users */ + /** + * Returns a variety of information about the user specified by the required user_id or screen_name parameter. + * The author's most recent Tweet will be returned inline when possible. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-show + */ + user(user) { + return this.get('users/show.json', { tweet_mode: 'extended', ...user }); + } + /** + * Returns fully-hydrated user objects for up to 100 users per request, + * as specified by comma-separated values passed to the user_id and/or screen_name parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup + */ + users(query) { + return this.get('users/lookup.json', { tweet_mode: 'extended', ...query }); + } + /** + * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; + * returns a 401 status code and an error message if not. + * Use this method to test if supplied user credentials are valid. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials + */ + verifyCredentials(options = {}) { + return this.get('account/verify_credentials.json', options); + } + /** + * Returns an array of user objects the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list + */ + async listMutedUsers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('mutes/users/list.json', queryParams, { fullResponse: true }); + return new MuteUserListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids the authenticating user has muted. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids + */ + async listMutedUserIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('mutes/users/ids.json', queryParams, { fullResponse: true }); + return new MuteUserIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of user objects of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-list + */ + async userFriendList(options = {}) { + const queryParams = { + ...options, + }; + const initialRq = await this.get('friends/list.json', queryParams, { fullResponse: true }); + return new UserFriendListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of user objects of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-list + */ + async userFollowerList(options = {}) { + const queryParams = { + ...options, + }; + const initialRq = await this.get('followers/list.json', queryParams, { fullResponse: true }); + return new UserFollowerListV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids of followers of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids + */ + async userFollowerIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('followers/ids.json', queryParams, { fullResponse: true }); + return new UserFollowerIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns an array of numeric user ids of friends of the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids + */ + async userFollowingIds(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friends/ids.json', queryParams, { fullResponse: true }); + return new UserFollowersIdsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Provides a simple, relevance-based search interface to public user accounts on Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search + */ + async searchUsers(query, options = {}) { + const queryParams = { + q: query, + tweet_mode: 'extended', + page: 1, + ...options, + }; + const initialRq = await this.get('users/search.json', queryParams, { fullResponse: true }); + return new UserSearchV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Friendship API */ + /** + * Returns detailed information about the relationship between two arbitrary users. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show + */ + friendship(sources) { + return this.get('friendships/show.json', sources); + } + /** + * Returns the relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup + */ + friendships(friendships) { + return this.get('friendships/lookup.json', friendships); + } + /** + * Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids + */ + friendshipsNoRetweets() { + return this.get('friendships/no_retweets/ids.json', { stringify_ids: true }); + } + /** + * Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming + */ + async friendshipsIncoming(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friendships/incoming.json', queryParams, { fullResponse: true }); + return new FriendshipsIncomingV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing + */ + async friendshipsOutgoing(options = {}) { + const queryParams = { + stringify_ids: true, + ...options, + }; + const initialRq = await this.get('friendships/outgoing.json', queryParams, { fullResponse: true }); + return new FriendshipsOutgoingV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Account/user API */ + /** + * Get current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + accountSettings() { + return this.get('account/settings.json'); + } + /** + * Returns a map of the available size variations of the specified user's profile banner. + * If the user has not uploaded a profile banner, a HTTP 404 will be served instead. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-users-profile_banner + */ + userProfileBannerSizes(params) { + return this.get('users/profile_banner.json', params); + } + /* Lists */ + /** + * Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-show + */ + list(options) { + return this.get('lists/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns all lists the authenticating or specified user subscribes to, including their own. + * If no user is given, the authenticating user is used. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-list + */ + lists(options = {}) { + return this.get('lists/list.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members + */ + async listMembers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/members.json', queryParams, { fullResponse: true }); + return new ListMembersV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Check if the specified user is a member of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show + */ + listGetMember(options) { + return this.get('lists/members/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Returns the lists the specified user has been added to. + * If user_id or screen_name are not provided, the memberships for the authenticating user are returned. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships + */ + async listMemberships(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/memberships.json', queryParams, { fullResponse: true }); + return new ListMembershipsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships + */ + async listOwnerships(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/ownerships.json', queryParams, { fullResponse: true }); + return new ListOwnershipsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a timeline of tweets authored by members of the specified list. Retweets are included by default. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses + */ + async listStatuses(options) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/statuses.json', queryParams, { fullResponse: true }); + return new ListTimelineV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers + */ + async listSubscribers(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/subscribers.json', queryParams, { fullResponse: true }); + return new ListSubscribersV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Check if the specified user is a subscriber of the specified list. Returns the user if they are a subscriber. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show + */ + listGetSubscriber(options) { + return this.get('lists/subscribers/show.json', { tweet_mode: 'extended', ...options }); + } + /** + * Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. + * Does not include the user's own lists. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions + */ + async listSubscriptions(options = {}) { + const queryParams = { + tweet_mode: 'extended', + ...options, + }; + const initialRq = await this.get('lists/subscriptions.json', queryParams, { fullResponse: true }); + return new ListSubscriptionsV1Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /* Media upload API */ + /** + * The STATUS command (this method) is used to periodically poll for updates of media processing operation. + * After the STATUS command response returns succeeded, you can move on to the next step which is usually create Tweet with media_id. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/get-media-upload-status + */ + mediaInfo(mediaId) { + return this.get('media/upload.json', { + command: 'STATUS', + media_id: mediaId, + }, { prefix: API_V1_1_UPLOAD_PREFIX }); + } + filterStream({ autoConnect, ...params } = {}) { + const parameters = {}; + for (const [key, value] of Object.entries(params)) { + if (key === 'follow' || key === 'track') { + parameters[key] = value.toString(); + } + else if (key === 'locations') { + const locations = value; + parameters.locations = arrayWrap(locations).map(loc => `${loc.lng},${loc.lat}`).join(','); + } + else { + parameters[key] = value; + } + } + const streamClient = this.stream; + return streamClient.postStream('statuses/filter.json', parameters, { autoConnect }); + } + sampleStream({ autoConnect, ...params } = {}) { + const streamClient = this.stream; + return streamClient.getStream('statuses/sample.json', params, { autoConnect }); + } + /** + * Create a client that is prefixed with `https//stream.twitter.com` instead of classic API URL. + */ + get stream() { + const copiedClient = new TwitterApiv1(this); + copiedClient.setPrefix(API_V1_1_STREAM_PREFIX); + return copiedClient; + } + /* Trends API */ + /** + * Returns the top 50 trending topics for a specific id, if trending information is available for it. + * Note: The id parameter for this endpoint is the "where on earth identifier" or WOEID, which is a legacy identifier created by Yahoo and has been deprecated. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/trends-for-location/api-reference/get-trends-place + */ + trendsByPlace(woeId, options = {}) { + return this.get('trends/place.json', { id: woeId, ...options }); + } + /** + * Returns the locations that Twitter has trending topic information for. + * The response is an array of "locations" that encode the location's WOEID + * and some other human-readable information such as a canonical name and country the location belongs in. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-available + */ + trendsAvailable() { + return this.get('trends/available.json'); + } + /** + * Returns the locations that Twitter has trending topic information for, closest to a specified location. + * https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-closest + */ + trendsClosest(lat, long) { + return this.get('trends/closest.json', { lat, long }); + } + /* Geo API */ + /** + * Returns all the information about a known place. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/place-information/api-reference/get-geo-id-place_id + */ + geoPlace(placeId) { + return this.get('geo/id/:place_id.json', undefined, { params: { place_id: placeId } }); + } + /** + * Search for places that can be attached to a Tweet via POST statuses/update. + * This request will return a list of all the valid places that can be used as the place_id when updating a status. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-search + */ + geoSearch(options) { + return this.get('geo/search.json', options); + } + /** + * Given a latitude and a longitude, searches for up to 20 places that can be used as a place_id when updating a status. + * This request is an informative call and will deliver generalized results about geography. + * https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-reverse_geocode + */ + geoReverseGeoCode(options) { + return this.get('geo/reverse_geocode.json', options); + } + /* Developer utilities */ + /** + * Returns the current rate limits for methods belonging to the specified resource families. + * Each API resource belongs to a "resource family" which is indicated in its method documentation. + * The method's resource family can be determined from the first component of the path after the resource version. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status + */ + rateLimitStatuses(...resources) { + return this.get('application/rate_limit_status.json', { resources }); + } + /** + * Returns the list of languages supported by Twitter along with the language code supported by Twitter. + * https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/supported-languages/api-reference/get-help-languages + */ + supportedLanguages() { + return this.get('help/languages.json'); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.d.ts b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.d.ts new file mode 100644 index 0000000..8f91cde --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.d.ts @@ -0,0 +1,172 @@ +import { AccountProfileV1Params, AccountSettingsV1, AccountSettingsV1Params, AddOrRemoveListMembersV1Params, FriendshipCreateOrDestroyV1, FriendshipCreateV1Params, FriendshipDestroyV1Params, FriendshipUpdateV1Params, FriendshipV1, GetListV1Params, ListCreateV1Params, ListV1, MediaMetadataV1Params, MediaStatusV1Result, MediaSubtitleV1Param, ProfileBannerUpdateV1Params, ProfileImageUpdateV1Params, ReportSpamV1Params, SendTweetV1Params, TUploadableMedia, TweetV1, UpdateListV1Params, UploadMediaV1Params, UserV1 } from '../types'; +import TwitterApiv1ReadOnly from './client.v1.read'; +import { TFileHandle } from './media-helpers.v1'; +/** + * Base Twitter v1 client with read/write rights. + */ +export default class TwitterApiv1ReadWrite extends TwitterApiv1ReadOnly { + protected _prefix: string; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv1ReadOnly; + /** + * Post a new tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweet(status: string, payload?: Partial): Promise; + /** + * Quote an existing tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + quote(status: string, quotingStatusId: string, payload?: Partial): Promise; + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweetThread(tweets: (SendTweetV1Params | string)[]): Promise; + /** + * Reply to an existing tweet. Shortcut to `.tweet` with tweaked parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + reply(status: string, in_reply_to_status_id: string, payload?: Partial): Promise; + /** + * Delete an existing tweet belonging to you. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id + */ + deleteTweet(tweetId: string): Promise; + /** + * Report the specified user as a spam account to Twitter. + * Additionally, optionally performs the equivalent of POST blocks/create on behalf of the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam + */ + reportUserAsSpam(options: ReportSpamV1Params): Promise; + /** + * Turn on/off Retweets and device notifications from the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update + */ + updateFriendship(options: Partial): Promise; + /** + * Follow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create + */ + createFriendship(options: Partial): Promise; + /** + * Unfollow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy + */ + destroyFriendship(options: Partial): Promise; + /** + * Update current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + updateAccountSettings(options: Partial): Promise; + /** + * Sets some values that users are able to set under the "Account" tab of their settings page. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile + */ + updateAccountProfile(options: Partial): Promise; + /** + * Uploads a profile banner on behalf of the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_banner + */ + updateAccountProfileBanner(file: TUploadableMedia, options?: Partial): Promise; + /** + * Updates the authenticating user's profile image. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image + */ + updateAccountProfileImage(file: TUploadableMedia, options?: Partial): Promise; + /** + * Removes the uploaded profile banner for the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-remove_profile_banner + */ + removeAccountProfileBanner(): Promise; + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-create + */ + createList(options: ListCreateV1Params): Promise; + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-update + */ + updateList(options: UpdateListV1Params): Promise; + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy + */ + removeList(options: GetListV1Params): Promise; + /** + * Adds multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/create.json`, otherwise + * it will target `lists/members/create_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all + */ + addListMembers(options: AddOrRemoveListMembersV1Params): Promise; + /** + * Removes multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/destroy.json`, otherwise + * it will target `lists/members/destroy_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all + */ + removeListMembers(options: AddOrRemoveListMembersV1Params): Promise; + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create + */ + subscribeToList(options: GetListV1Params): Promise; + /** + * Unsubscribes the authenticated user of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy + */ + unsubscribeOfList(options: GetListV1Params): Promise; + /** + * This endpoint can be used to provide additional information about the uploaded media_id. + * This feature is currently only supported for images and GIFs. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-metadata-create + */ + createMediaMetadata(mediaId: string, metadata: Partial): Promise; + /** + * Use this endpoint to associate uploaded subtitles to an uploaded video. You can associate subtitles to video before or after Tweeting. + * **To obtain subtitle media ID, you must upload each subtitle file separately using `.uploadMedia()` method.** + * + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-create + */ + createMediaSubtitles(mediaId: string, subtitles: MediaSubtitleV1Param[]): Promise; + /** + * Use this endpoint to dissociate subtitles from a video and delete the subtitles. You can dissociate subtitles from a video before or after Tweeting. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-delete + */ + deleteMediaSubtitles(mediaId: string, ...languages: string[]): Promise; + /** + * Upload a media (JPG/PNG/GIF/MP4/MOV/WEBP) or subtitle (SRT) to Twitter and return the media_id to use in tweet/DM send. + * + * @param file If `string`, filename is supposed. + * A `Buffer` is a raw file. + * `fs.promises.FileHandle` or `number` are file pointers. + * + * @param options.type File type (Enum 'jpg' | 'longmp4' | 'mp4' | 'mov | 'png' | 'gif' | 'srt' | 'webp'). + * If filename is given, it could be guessed with file extension, otherwise this parameter is mandatory. + * If type is not part of the enum, it will be used as mime type. + * + * Type `longmp4` is **required** is you try to upload a video higher than 140 seconds. + * + * @param options.chunkLength Maximum chunk length sent to Twitter. Default goes to 1 MB. + * + * @param options.additionalOwners Other user IDs allowed to use the returned media_id. Default goes to none. + * + * @param options.maxConcurrentUploads Maximum uploaded chunks in the same time. Default goes to 3. + * + * @param options.target Target type `tweet` or `dm`. Defaults to `tweet`. + * You must specify it if you send a media to use in DMs. + */ + uploadMedia(file: TUploadableMedia, options?: Partial): Promise; + protected awaitForMediaProcessingCompletion(fullMediaData: MediaStatusV1Result): Promise; + protected getUploadMediaRequirements(file: TUploadableMedia, { mimeType, type, target, longVideo }?: Partial): Promise<{ + fileHandle: TFileHandle; + mediaCategory: string; + fileSize: number; + mimeType: string; + }>; + protected mediaChunkedUpload(fileHandle: TFileHandle, chunkLength: number, mediaId: string, maxConcurrentUploads?: number): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.js b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.js new file mode 100644 index 0000000..b8c06a5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.js @@ -0,0 +1,413 @@ +import * as fs from 'fs'; +import { API_V1_1_PREFIX, API_V1_1_UPLOAD_PREFIX } from '../globals'; +import { hasMultipleItems } from '../helpers'; +import { EUploadMimeType, } from '../types'; +import TwitterApiv1ReadOnly from './client.v1.read'; +import { getFileHandle, getFileSizeFromFileHandle, getMediaCategoryByMime, getMimeType, readFileIntoBuffer, readNextPartOf, sleepSecs } from './media-helpers.v1'; +const UPLOAD_ENDPOINT = 'media/upload.json'; +/** + * Base Twitter v1 client with read/write rights. + */ +export default class TwitterApiv1ReadWrite extends TwitterApiv1ReadOnly { + constructor() { + super(...arguments); + this._prefix = API_V1_1_PREFIX; + } + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } + /* Tweet API */ + /** + * Post a new tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + tweet(status, payload = {}) { + const queryParams = { + status, + tweet_mode: 'extended', + ...payload, + }; + return this.post('statuses/update.json', queryParams); + } + /** + * Quote an existing tweet. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + async quote(status, quotingStatusId, payload = {}) { + const url = 'https://twitter.com/i/statuses/' + quotingStatusId; + return this.tweet(status, { ...payload, attachment_url: url }); + } + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + async tweetThread(tweets) { + const postedTweets = []; + for (const tweet of tweets) { + // Retrieve the last sent tweet + const lastTweet = postedTweets.length ? postedTweets[postedTweets.length - 1] : null; + // Build the tweet query params + const queryParams = { ...(typeof tweet === 'string' ? ({ status: tweet }) : tweet) }; + // Reply to an existing tweet if needed + const inReplyToId = lastTweet ? lastTweet.id_str : queryParams.in_reply_to_status_id; + const status = queryParams.status; + if (inReplyToId) { + postedTweets.push(await this.reply(status, inReplyToId, queryParams)); + } + else { + postedTweets.push(await this.tweet(status, queryParams)); + } + } + return postedTweets; + } + /** + * Reply to an existing tweet. Shortcut to `.tweet` with tweaked parameters. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update + */ + reply(status, in_reply_to_status_id, payload = {}) { + return this.tweet(status, { + auto_populate_reply_metadata: true, + in_reply_to_status_id, + ...payload, + }); + } + /** + * Delete an existing tweet belonging to you. + * https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id + */ + deleteTweet(tweetId) { + return this.post('statuses/destroy/:id.json', { tweet_mode: 'extended' }, { params: { id: tweetId } }); + } + /* User API */ + /** + * Report the specified user as a spam account to Twitter. + * Additionally, optionally performs the equivalent of POST blocks/create on behalf of the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam + */ + reportUserAsSpam(options) { + return this.post('users/report_spam.json', { tweet_mode: 'extended', ...options }); + } + /** + * Turn on/off Retweets and device notifications from the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update + */ + updateFriendship(options) { + return this.post('friendships/update.json', options); + } + /** + * Follow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create + */ + createFriendship(options) { + return this.post('friendships/create.json', options); + } + /** + * Unfollow the specified user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy + */ + destroyFriendship(options) { + return this.post('friendships/destroy.json', options); + } + /* Account API */ + /** + * Update current account settings for authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/get-account-settings + */ + updateAccountSettings(options) { + return this.post('account/settings.json', options); + } + /** + * Sets some values that users are able to set under the "Account" tab of their settings page. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile + */ + updateAccountProfile(options) { + return this.post('account/update_profile.json', options); + } + /** + * Uploads a profile banner on behalf of the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_banner + */ + async updateAccountProfileBanner(file, options = {}) { + const queryParams = { + banner: await readFileIntoBuffer(file), + ...options, + }; + return this.post('account/update_profile_banner.json', queryParams, { forceBodyMode: 'form-data' }); + } + /** + * Updates the authenticating user's profile image. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image + */ + async updateAccountProfileImage(file, options = {}) { + const queryParams = { + tweet_mode: 'extended', + image: await readFileIntoBuffer(file), + ...options, + }; + return this.post('account/update_profile_image.json', queryParams, { forceBodyMode: 'form-data' }); + } + /** + * Removes the uploaded profile banner for the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-remove_profile_banner + */ + removeAccountProfileBanner() { + return this.post('account/remove_profile_banner.json'); + } + /* Lists */ + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-create + */ + createList(options) { + return this.post('lists/create.json', { tweet_mode: 'extended', ...options }); + } + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-update + */ + updateList(options) { + return this.post('lists/update.json', { tweet_mode: 'extended', ...options }); + } + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy + */ + removeList(options) { + return this.post('lists/destroy.json', { tweet_mode: 'extended', ...options }); + } + /** + * Adds multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/create.json`, otherwise + * it will target `lists/members/create_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all + */ + addListMembers(options) { + const hasMultiple = (options.user_id && hasMultipleItems(options.user_id)) || (options.screen_name && hasMultipleItems(options.screen_name)); + const endpoint = hasMultiple ? 'lists/members/create_all.json' : 'lists/members/create.json'; + return this.post(endpoint, options); + } + /** + * Removes multiple members to a list, by specifying a comma-separated list of member ids or screen names. + * If you add a single `user_id` or `screen_name`, it will target `lists/members/destroy.json`, otherwise + * it will target `lists/members/destroy_all.json`. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all + */ + removeListMembers(options) { + const hasMultiple = (options.user_id && hasMultipleItems(options.user_id)) || (options.screen_name && hasMultipleItems(options.screen_name)); + const endpoint = hasMultiple ? 'lists/members/destroy_all.json' : 'lists/members/destroy.json'; + return this.post(endpoint, options); + } + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create + */ + subscribeToList(options) { + return this.post('lists/subscribers/create.json', { tweet_mode: 'extended', ...options }); + } + /** + * Unsubscribes the authenticated user of the specified list. + * https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy + */ + unsubscribeOfList(options) { + return this.post('lists/subscribers/destroy.json', { tweet_mode: 'extended', ...options }); + } + /* Media upload API */ + /** + * This endpoint can be used to provide additional information about the uploaded media_id. + * This feature is currently only supported for images and GIFs. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-metadata-create + */ + createMediaMetadata(mediaId, metadata) { + return this.post('media/metadata/create.json', { media_id: mediaId, ...metadata }, { prefix: API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Use this endpoint to associate uploaded subtitles to an uploaded video. You can associate subtitles to video before or after Tweeting. + * **To obtain subtitle media ID, you must upload each subtitle file separately using `.uploadMedia()` method.** + * + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-create + */ + createMediaSubtitles(mediaId, subtitles) { + return this.post('media/subtitles/create.json', { media_id: mediaId, media_category: 'TweetVideo', subtitle_info: { subtitles } }, { prefix: API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Use this endpoint to dissociate subtitles from a video and delete the subtitles. You can dissociate subtitles from a video before or after Tweeting. + * https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-subtitles-delete + */ + deleteMediaSubtitles(mediaId, ...languages) { + return this.post('media/subtitles/delete.json', { + media_id: mediaId, + media_category: 'TweetVideo', + subtitle_info: { subtitles: languages.map(lang => ({ language_code: lang })) }, + }, { prefix: API_V1_1_UPLOAD_PREFIX, forceBodyMode: 'json' }); + } + /** + * Upload a media (JPG/PNG/GIF/MP4/MOV/WEBP) or subtitle (SRT) to Twitter and return the media_id to use in tweet/DM send. + * + * @param file If `string`, filename is supposed. + * A `Buffer` is a raw file. + * `fs.promises.FileHandle` or `number` are file pointers. + * + * @param options.type File type (Enum 'jpg' | 'longmp4' | 'mp4' | 'mov | 'png' | 'gif' | 'srt' | 'webp'). + * If filename is given, it could be guessed with file extension, otherwise this parameter is mandatory. + * If type is not part of the enum, it will be used as mime type. + * + * Type `longmp4` is **required** is you try to upload a video higher than 140 seconds. + * + * @param options.chunkLength Maximum chunk length sent to Twitter. Default goes to 1 MB. + * + * @param options.additionalOwners Other user IDs allowed to use the returned media_id. Default goes to none. + * + * @param options.maxConcurrentUploads Maximum uploaded chunks in the same time. Default goes to 3. + * + * @param options.target Target type `tweet` or `dm`. Defaults to `tweet`. + * You must specify it if you send a media to use in DMs. + */ + async uploadMedia(file, options = {}) { + var _a; + const chunkLength = (_a = options.chunkLength) !== null && _a !== void 0 ? _a : (1024 * 1024); + const { fileHandle, mediaCategory, fileSize, mimeType } = await this.getUploadMediaRequirements(file, options); + // Get the file handle (if not buffer) + try { + // Finally! We can send INIT message. + const mediaData = await this.post(UPLOAD_ENDPOINT, { + command: 'INIT', + total_bytes: fileSize, + media_type: mimeType, + media_category: mediaCategory, + additional_owners: options.additionalOwners, + shared: options.shared ? true : undefined, + }, { prefix: API_V1_1_UPLOAD_PREFIX }); + // Upload the media chunk by chunk + await this.mediaChunkedUpload(fileHandle, chunkLength, mediaData.media_id_string, options.maxConcurrentUploads); + // Finalize media + const fullMediaData = await this.post(UPLOAD_ENDPOINT, { + command: 'FINALIZE', + media_id: mediaData.media_id_string, + }, { prefix: API_V1_1_UPLOAD_PREFIX }); + if (fullMediaData.processing_info && fullMediaData.processing_info.state !== 'succeeded') { + // Must wait if video is still computed + await this.awaitForMediaProcessingCompletion(fullMediaData); + } + // Video is ready, return media_id + return fullMediaData.media_id_string; + } + finally { + // Close file if any + if (typeof file === 'number') { + // eslint-disable-next-line @typescript-eslint/no-empty-function + fs.close(file, () => { }); + } + else if (typeof fileHandle === 'object' && !(fileHandle instanceof Buffer)) { + fileHandle.close(); + } + } + } + async awaitForMediaProcessingCompletion(fullMediaData) { + // eslint-disable-next-line no-constant-condition + while (true) { + fullMediaData = await this.mediaInfo(fullMediaData.media_id_string); + const { processing_info } = fullMediaData; + if (!processing_info || processing_info.state === 'succeeded') { + // Ok, completed! + return; + } + if (processing_info.state === 'failed') { + if (processing_info.error) { + const { name, message } = processing_info.error; + throw new Error(`Failed to process media: ${name} - ${message}.`); + } + throw new Error('Failed to process the media.'); + } + if (processing_info.check_after_secs) { + // Await for given seconds + await sleepSecs(processing_info.check_after_secs); + } + else { + // No info; Await for 5 seconds + await sleepSecs(5); + } + } + } + async getUploadMediaRequirements(file, { mimeType, type, target, longVideo } = {}) { + // Get the file handle (if not buffer) + let fileHandle; + try { + fileHandle = await getFileHandle(file); + // Get the mimetype + const realMimeType = getMimeType(file, type, mimeType); + // Get the media category + let mediaCategory; + // If explicit longmp4 OR explicit MIME type and not DM target + if (realMimeType === EUploadMimeType.Mp4 && ((!mimeType && !type && target !== 'dm') || longVideo)) { + mediaCategory = 'amplify_video'; + } + else { + mediaCategory = getMediaCategoryByMime(realMimeType, target !== null && target !== void 0 ? target : 'tweet'); + } + return { + fileHandle, + mediaCategory, + fileSize: await getFileSizeFromFileHandle(fileHandle), + mimeType: realMimeType, + }; + } + catch (e) { + // Close file if any + if (typeof file === 'number') { + // eslint-disable-next-line @typescript-eslint/no-empty-function + fs.close(file, () => { }); + } + else if (typeof fileHandle === 'object' && !(fileHandle instanceof Buffer)) { + fileHandle.close(); + } + throw e; + } + } + async mediaChunkedUpload(fileHandle, chunkLength, mediaId, maxConcurrentUploads = 3) { + // Send chunk by chunk + let chunkIndex = 0; + if (maxConcurrentUploads < 1) { + throw new RangeError('Bad maxConcurrentUploads parameter.'); + } + // Creating a buffer for doing file stuff (if we don't have one) + const buffer = fileHandle instanceof Buffer ? undefined : Buffer.alloc(chunkLength); + // Sliced/filled buffer returned for each part + let readBuffer; + // Needed to know when we should stop reading the file + let nread; + // Needed to use the buffer object (file handles always "remembers" file position) + let offset = 0; + [readBuffer, nread] = await readNextPartOf(fileHandle, chunkLength, offset, buffer); + offset += nread; + // Handle max concurrent uploads + const currentUploads = new Set(); + // Read buffer until file is completely read + while (nread) { + const mediaBufferPart = readBuffer.slice(0, nread); + // Sent part if part has something inside + if (mediaBufferPart.length) { + const request = this.post(UPLOAD_ENDPOINT, { + command: 'APPEND', + media_id: mediaId, + segment_index: chunkIndex, + media: mediaBufferPart, + }, { prefix: API_V1_1_UPLOAD_PREFIX }); + currentUploads.add(request); + request.then(() => { + currentUploads.delete(request); + }); + chunkIndex++; + } + if (currentUploads.size >= maxConcurrentUploads) { + // Await for first promise to be finished + await Promise.race(currentUploads); + } + [readBuffer, nread] = await readNextPartOf(fileHandle, chunkLength, offset, buffer); + offset += nread; + } + await Promise.all([...currentUploads]); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.d.ts b/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.d.ts new file mode 100644 index 0000000..f786bdd --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.d.ts @@ -0,0 +1,13 @@ +/// +/// +import * as fs from 'fs'; +import type { TUploadableMedia, TUploadTypeV1 } from '../types'; +import { EUploadMimeType } from '../types'; +export declare type TFileHandle = fs.promises.FileHandle | number | Buffer; +export declare function readFileIntoBuffer(file: TUploadableMedia): Promise; +export declare function getFileHandle(file: TUploadableMedia): number | Buffer | fs.promises.FileHandle | Promise; +export declare function getFileSizeFromFileHandle(fileHandle: TFileHandle): Promise; +export declare function getMimeType(file: TUploadableMedia, type?: TUploadTypeV1 | string, mimeType?: EUploadMimeType | string): string; +export declare function getMediaCategoryByMime(name: string, target: 'tweet' | 'dm'): "TweetVideo" | "DmVideo" | "TweetGif" | "DmGif" | "Subtitles" | "TweetImage" | "DmImage"; +export declare function sleepSecs(seconds: number): Promise; +export declare function readNextPartOf(file: TFileHandle, chunkLength: number, bufferOffset?: number, buffer?: Buffer): Promise<[Buffer, number]>; diff --git a/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.js b/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.js new file mode 100644 index 0000000..1d1f834 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v1/media-helpers.v1.js @@ -0,0 +1,154 @@ +import * as fs from 'fs'; +import { safeDeprecationWarning } from '../helpers'; +import { EUploadMimeType } from '../types'; +export async function readFileIntoBuffer(file) { + const handle = await getFileHandle(file); + if (typeof handle === 'number') { + return new Promise((resolve, reject) => { + fs.readFile(handle, (err, data) => { + if (err) { + return reject(err); + } + resolve(data); + }); + }); + } + else if (handle instanceof Buffer) { + return handle; + } + else { + return handle.readFile(); + } +} +export function getFileHandle(file) { + if (typeof file === 'string') { + return fs.promises.open(file, 'r'); + } + else if (typeof file === 'number') { + return file; + } + else if (typeof file === 'object' && !(file instanceof Buffer)) { + return file; + } + else if (!(file instanceof Buffer)) { + throw new Error('Given file is not valid, please check its type.'); + } + else { + return file; + } +} +export async function getFileSizeFromFileHandle(fileHandle) { + // Get the file size + if (typeof fileHandle === 'number') { + const stats = await new Promise((resolve, reject) => { + fs.fstat(fileHandle, (err, stats) => { + if (err) + reject(err); + resolve(stats); + }); + }); + return stats.size; + } + else if (fileHandle instanceof Buffer) { + return fileHandle.length; + } + else { + return (await fileHandle.stat()).size; + } +} +export function getMimeType(file, type, mimeType) { + if (typeof mimeType === 'string') { + return mimeType; + } + else if (typeof file === 'string' && !type) { + return getMimeByName(file); + } + else if (typeof type === 'string') { + return getMimeByType(type); + } + throw new Error('You must specify type if file is a file handle or Buffer.'); +} +function getMimeByName(name) { + if (name.endsWith('.jpeg') || name.endsWith('.jpg')) + return EUploadMimeType.Jpeg; + if (name.endsWith('.png')) + return EUploadMimeType.Png; + if (name.endsWith('.webp')) + return EUploadMimeType.Webp; + if (name.endsWith('.gif')) + return EUploadMimeType.Gif; + if (name.endsWith('.mpeg4') || name.endsWith('.mp4')) + return EUploadMimeType.Mp4; + if (name.endsWith('.mov') || name.endsWith('.mov')) + return EUploadMimeType.Mov; + if (name.endsWith('.srt')) + return EUploadMimeType.Srt; + safeDeprecationWarning({ + instance: 'TwitterApiv1ReadWrite', + method: 'uploadMedia', + problem: 'options.mimeType is missing and filename couldn\'t help to resolve MIME type, so it will fallback to image/jpeg', + resolution: 'If you except to give filenames without extensions, please specify explicitlty the MIME type using options.mimeType', + }); + return EUploadMimeType.Jpeg; +} +function getMimeByType(type) { + safeDeprecationWarning({ + instance: 'TwitterApiv1ReadWrite', + method: 'uploadMedia', + problem: 'you\'re using options.type', + resolution: 'Remove options.type argument and migrate to options.mimeType which takes the real MIME type. ' + + 'If you\'re using type=longmp4, add options.longVideo alongside of mimeType=EUploadMimeType.Mp4', + }); + if (type === 'gif') + return EUploadMimeType.Gif; + if (type === 'jpg') + return EUploadMimeType.Jpeg; + if (type === 'png') + return EUploadMimeType.Png; + if (type === 'webp') + return EUploadMimeType.Webp; + if (type === 'srt') + return EUploadMimeType.Srt; + if (type === 'mp4' || type === 'longmp4') + return EUploadMimeType.Mp4; + if (type === 'mov') + return EUploadMimeType.Mov; + return type; +} +export function getMediaCategoryByMime(name, target) { + if (name === EUploadMimeType.Mp4 || name === EUploadMimeType.Mov) + return target === 'tweet' ? 'TweetVideo' : 'DmVideo'; + if (name === EUploadMimeType.Gif) + return target === 'tweet' ? 'TweetGif' : 'DmGif'; + if (name === EUploadMimeType.Srt) + return 'Subtitles'; + else + return target === 'tweet' ? 'TweetImage' : 'DmImage'; +} +export function sleepSecs(seconds) { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)); +} +export async function readNextPartOf(file, chunkLength, bufferOffset = 0, buffer) { + if (file instanceof Buffer) { + const rt = file.slice(bufferOffset, bufferOffset + chunkLength); + return [rt, rt.length]; + } + if (!buffer) { + throw new Error('Well, we will need a buffer to store file content.'); + } + let bytesRead; + if (typeof file === 'number') { + bytesRead = await new Promise((resolve, reject) => { + fs.read(file, buffer, 0, chunkLength, bufferOffset, (err, nread) => { + if (err) + reject(err); + resolve(nread); + }); + }); + } + else { + const res = await file.read(buffer, 0, chunkLength, bufferOffset); + bytesRead = res.bytesRead; + } + return [buffer, bytesRead]; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.d.ts b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.d.ts new file mode 100644 index 0000000..fe37424 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.d.ts @@ -0,0 +1,12 @@ +import TwitterApiv2LabsReadWrite from './client.v2.labs.write'; +/** + * Twitter v2 labs client with all rights (read/write/DMs) + */ +export declare class TwitterApiv2Labs extends TwitterApiv2LabsReadWrite { + protected _prefix: string; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv2LabsReadWrite; +} +export default TwitterApiv2Labs; diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.js b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.js new file mode 100644 index 0000000..5370c96 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.js @@ -0,0 +1,18 @@ +import { API_V2_LABS_PREFIX } from '../globals'; +import TwitterApiv2LabsReadWrite from './client.v2.labs.write'; +/** + * Twitter v2 labs client with all rights (read/write/DMs) + */ +export class TwitterApiv2Labs extends TwitterApiv2LabsReadWrite { + constructor() { + super(...arguments); + this._prefix = API_V2_LABS_PREFIX; + } + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } +} +export default TwitterApiv2Labs; diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.d.ts b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.d.ts new file mode 100644 index 0000000..fb79198 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.d.ts @@ -0,0 +1,7 @@ +import TwitterApiSubClient from '../client.subclient'; +/** + * Base Twitter v2 labs client with only read right. + */ +export default class TwitterApiv2LabsReadOnly extends TwitterApiSubClient { + protected _prefix: string; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.js b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.js new file mode 100644 index 0000000..11a1500 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.read.js @@ -0,0 +1,11 @@ +import TwitterApiSubClient from '../client.subclient'; +import { API_V2_LABS_PREFIX } from '../globals'; +/** + * Base Twitter v2 labs client with only read right. + */ +export default class TwitterApiv2LabsReadOnly extends TwitterApiSubClient { + constructor() { + super(...arguments); + this._prefix = API_V2_LABS_PREFIX; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.d.ts b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.d.ts new file mode 100644 index 0000000..d546f64 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.d.ts @@ -0,0 +1,11 @@ +import TwitterApiv2LabsReadOnly from './client.v2.labs.read'; +/** + * Base Twitter v2 labs client with read/write rights. + */ +export default class TwitterApiv2LabsReadWrite extends TwitterApiv2LabsReadOnly { + protected _prefix: string; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv2LabsReadOnly; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.js b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.js new file mode 100644 index 0000000..8454fe1 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2-labs/client.v2.labs.write.js @@ -0,0 +1,17 @@ +import { API_V2_LABS_PREFIX } from '../globals'; +import TwitterApiv2LabsReadOnly from './client.v2.labs.read'; +/** + * Base Twitter v2 labs client with read/write rights. + */ +export default class TwitterApiv2LabsReadWrite extends TwitterApiv2LabsReadOnly { + constructor() { + super(...arguments); + this._prefix = API_V2_LABS_PREFIX; + } + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.d.ts b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.d.ts new file mode 100644 index 0000000..9caf1a0 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.d.ts @@ -0,0 +1,18 @@ +import TwitterApiv2ReadWrite from './client.v2.write'; +import TwitterApiv2Labs from '../v2-labs/client.v2.labs'; +/** + * Twitter v2 client with all rights (read/write/DMs) + */ +export declare class TwitterApiv2 extends TwitterApiv2ReadWrite { + protected _prefix: string; + protected _labs?: TwitterApiv2Labs; + /** + * Get a client with read/write rights. + */ + get readWrite(): TwitterApiv2ReadWrite; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2Labs; +} +export default TwitterApiv2; diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.js b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.js new file mode 100644 index 0000000..12fd7b5 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.js @@ -0,0 +1,29 @@ +import { API_V2_PREFIX } from '../globals'; +import TwitterApiv2ReadWrite from './client.v2.write'; +import TwitterApiv2Labs from '../v2-labs/client.v2.labs'; +/** + * Twitter v2 client with all rights (read/write/DMs) + */ +export class TwitterApiv2 extends TwitterApiv2ReadWrite { + constructor() { + super(...arguments); + this._prefix = API_V2_PREFIX; + /** API endpoints */ + } + /* Sub-clients */ + /** + * Get a client with read/write rights. + */ + get readWrite() { + return this; + } + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new TwitterApiv2Labs(this); + } +} +export default TwitterApiv2; diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.d.ts b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.d.ts new file mode 100644 index 0000000..d9f2637 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.d.ts @@ -0,0 +1,352 @@ +import TwitterApiSubClient from '../client.subclient'; +import { Tweetv2FieldsParams, Tweetv2SearchParams, UserV2Result, UsersV2Result, UsersV2Params, StreamingV2GetRulesParams, StreamingV2GetRulesResult, TweetV2LookupResult, TweetV2UserTimelineParams, StreamingV2AddRulesParams, StreamingV2DeleteRulesParams, StreamingV2UpdateRulesQuery, StreamingV2UpdateRulesDeleteResult, StreamingV2UpdateRulesAddResult, TweetV2SingleResult, TweetV2PaginableTimelineParams, TweetV2CountResult, TweetV2CountParams, TweetV2CountAllResult, TweetV2CountAllParams, TweetV2RetweetedByResult, TweetV2LikedByResult, UserV2TimelineParams, UserV2TimelineResult, FollowersV2ParamsWithPaginator, FollowersV2ParamsWithoutPaginator, TweetSearchV2StreamParams, TweetV2SingleStreamResult, TweetV2PaginableListParams, SpaceV2FieldsParams, SpaceV2LookupResult, SpaceV2CreatorLookupParams, SpaceV2SearchParams, SpaceV2SingleResult, BatchComplianceSearchV2Params, BatchComplianceListV2Result, BatchComplianceV2Result, BatchComplianceV2Params, BatchComplianceV2JobResult, BatchComplianceJobV2, GetListV2Params, ListGetV2Result, GetListTimelineV2Params, TweetRetweetedOrLikedByV2ParamsWithPaginator, TweetRetweetedOrLikedByV2ParamsWithoutPaginator, SpaceV2BuyersParams, TweetV2HomeTimelineParams } from '../types'; +import { TweetSearchAllV2Paginator, TweetSearchRecentV2Paginator, TweetUserMentionTimelineV2Paginator, TweetUserTimelineV2Paginator, TweetV2UserLikedTweetsPaginator, UserOwnedListsV2Paginator, UserListMembershipsV2Paginator, UserListFollowedV2Paginator, TweetV2ListTweetsPaginator, TweetBookmarksTimelineV2Paginator, QuotedTweetsTimelineV2Paginator, TweetHomeTimelineV2Paginator } from '../paginators'; +import TwitterApiv2LabsReadOnly from '../v2-labs/client.v2.labs.read'; +import { TweetLikingUsersV2Paginator, TweetRetweetersUsersV2Paginator, UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator, UserListFollowersV2Paginator, UserListMembersV2Paginator, UserMutingUsersV2Paginator } from '../paginators/user.paginator.v2'; +import TweetStream from '../stream/TweetStream'; +import { PromiseOrType } from '../types/shared.types'; +import { GetDMEventV2Params } from '../types/v2/dm.v2.types'; +import { ConversationDMTimelineV2Paginator, FullDMTimelineV2Paginator, OneToOneDMTimelineV2Paginator } from '../paginators/dm.paginator.v2'; +/** + * Base Twitter v2 client with only read right. + */ +export default class TwitterApiv2ReadOnly extends TwitterApiSubClient { + protected _prefix: string; + protected _labs?: TwitterApiv2LabsReadOnly; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2LabsReadOnly; + /** + * The recent search endpoint returns Tweets from the last seven days that match a search query. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent + */ + search(options: Tweetv2SearchParams): Promise; + search(query: string, options?: Partial): Promise; + /** + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all + */ + searchAll(query: string, options?: Partial): Promise; + /** + * Returns a variety of information about a single Tweet specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + singleTweet(tweetId: string, options?: Partial): Promise; + /** + * Returns a variety of information about tweets specified by list of IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + tweets(tweetIds: string | string[], options?: Partial): Promise; + /** + * The recent Tweet counts endpoint returns count of Tweets from the last seven days that match a search query. + * OAuth2 Bearer auth only. + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + */ + tweetCountRecent(query: string, options?: Partial): Promise; + /** + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * OAuth2 Bearer auth only. + * **This endpoint has pagination, yet it is not supported by bundled paginators. Use `next_token` to fetch next page.** + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + */ + tweetCountAll(query: string, options?: Partial): Promise; + /** + * Allows you to get information about who has Retweeted a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/get-tweets-id-retweeted_by + */ + tweetRetweetedBy(tweetId: string, options?: Partial): Promise; + tweetRetweetedBy(tweetId: string, options: TweetRetweetedOrLikedByV2ParamsWithPaginator): Promise; + /** + * Allows you to get information about who has Liked a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users + */ + tweetLikedBy(tweetId: string, options?: Partial): Promise; + tweetLikedBy(tweetId: string, options: TweetRetweetedOrLikedByV2ParamsWithPaginator): Promise; + /** + * Allows you to retrieve a collection of the most recent Tweets and Retweets posted by you and users you follow, also known as home timeline. + * This endpoint returns up to the last 3200 Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological + * + * OAuth 2 scopes: `tweet.read` `users.read` + */ + homeTimeline(options?: Partial): Promise; + /** + * Returns Tweets composed by a single user, specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, the most recent 3,200 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + */ + userTimeline(userId: string, options?: Partial): Promise; + /** + * Returns Tweets mentioning a single user specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, up to the most recent 800 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions + */ + userMentionTimeline(userId: string, options?: Partial): Promise; + /** + * Returns Quote Tweets for a Tweet specified by the requested Tweet ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets + * + * OAuth2 scopes: `users.read` `tweet.read` + */ + quotes(tweetId: string, options?: Partial): Promise; + /** + * Allows you to get information about a authenticated user’s 800 most recent bookmarked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.read` + */ + bookmarks(options?: Partial): Promise; + /** + * Returns information about an authorized user. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me + * + * OAuth2 scopes: `tweet.read` & `users.read` + */ + me(options?: Partial): Promise; + /** + * Returns a variety of information about a single user specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-id + */ + user(userId: string, options?: Partial): Promise; + /** + * Returns a variety of information about one or more users specified by the requested IDs. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users + */ + users(userIds: string | string[], options?: Partial): Promise; + /** + * Returns a variety of information about a single user specified by their username. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username + */ + userByUsername(username: string, options?: Partial): Promise; + /** + * Returns a variety of information about one or more users specified by their usernames. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + usersByUsernames(usernames: string | string[], options?: Partial): Promise; + /** + * Returns a list of users who are followers of the specified user ID. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers + */ + followers(userId: string, options?: Partial): Promise; + followers(userId: string, options: FollowersV2ParamsWithPaginator): Promise; + /** + * Returns a list of users the specified user ID is following. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-following + * + * OAuth2 scope: `follows.read` + */ + following(userId: string, options?: Partial): Promise; + following(userId: string, options: FollowersV2ParamsWithPaginator): Promise; + /** + * Allows you to get information about a user’s liked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + */ + userLikedTweets(userId: string, options?: Partial): Promise; + /** + * Returns a list of users who are blocked by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + */ + userBlockingUsers(userId: string, options?: Partial): Promise; + /** + * Returns a list of users who are muted by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting + */ + userMutingUsers(userId: string, options?: Partial): Promise; + /** + * Returns the details of a specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + */ + list(id: string, options?: Partial): Promise; + /** + * Returns all Lists owned by the specified user. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists + */ + listsOwned(userId: string, options?: Partial): Promise; + /** + * Returns all Lists a specified user is a member of. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-users-id-list_memberships + */ + listMemberships(userId: string, options?: Partial): Promise; + /** + * Returns all Lists a specified user follows. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-users-id-followed_lists + */ + listFollowed(userId: string, options?: Partial): Promise; + /** + * Returns a list of Tweets from the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-tweets/api-reference/get-lists-id-tweets + */ + listTweets(listId: string, options?: Partial): Promise; + /** + * Returns a list of users who are members of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-lists-id-members + */ + listMembers(listId: string, options?: Partial): Promise; + /** + * Returns a list of users who are followers of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-lists-id-followers + */ + listFollowers(listId: string, options?: Partial): Promise; + /** + * Returns a list of Direct Messages for the authenticated user, both sent and received. + * Direct Message events are returned in reverse chronological order. + * Supports retrieving events from the previous 30 days. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_events + */ + listDmEvents(options?: Partial): Promise; + /** + * Returns a list of Direct Messages (DM) events within a 1-1 conversation with the user specified in the participant_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + listDmEventsWithParticipant(participantId: string, options?: Partial): Promise; + /** + * Returns a list of Direct Messages within a conversation specified in the dm_conversation_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + listDmEventsOfConversation(dmConversationId: string, options?: Partial): Promise; + /** + * Get a single space by ID. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + space(spaceId: string, options?: Partial): Promise; + /** + * Get spaces using their IDs. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaces(spaceIds: string | string[], options?: Partial): Promise; + /** + * Get spaces using their creator user ID(s). (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spacesByCreators(creatorIds: string | string[], options?: Partial): Promise; + /** + * Search through spaces using multiple params. (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search + */ + searchSpaces(options: SpaceV2SearchParams): Promise; + /** + * Returns a list of user who purchased a ticket to the requested Space. + * You must authenticate the request using the Access Token of the creator of the requested Space. + * + * **OAuth 2.0 Access Token required** + * + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-buyers + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaceBuyers(spaceId: string, options?: Partial): Promise; + /** + * Returns Tweets shared in the requested Spaces. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-tweets + * + * OAuth2 scope: `users.read`, `tweet.read`, `space.read` + */ + spaceTweets(spaceId: string, options?: Partial): Promise; + /** + * Streams Tweets in real-time based on a specific set of filter rules. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream + */ + searchStream(options?: Partial & { + autoConnect?: true; + }): Promise>; + searchStream(options: Partial & { + autoConnect: false; + }): TweetStream; + searchStream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Return a list of rules currently active on the streaming endpoint, either as a list or individually. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules + */ + streamRules(options?: Partial): Promise; + /** + * Add or delete rules to your stream. + * To create one or more rules, submit an add JSON body with an array of rules and operators. + * Similarly, to delete one or more rules, submit a delete JSON body with an array of list of existing rule IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules + */ + updateStreamRules(options: StreamingV2AddRulesParams, query?: Partial): Promise; + updateStreamRules(options: StreamingV2DeleteRulesParams, query?: Partial): Promise; + /** + * Streams about 1% of all Tweets in real-time. + * https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream + */ + sampleStream(options?: Partial & { + autoConnect?: true; + }): Promise>; + sampleStream(options: Partial & { + autoConnect: false; + }): TweetStream; + sampleStream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Streams about 10% of all Tweets in real-time. + * https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample10-stream + */ + sample10Stream(options?: Partial & { + autoConnect?: true; + }): Promise>; + sample10Stream(options: Partial & { + autoConnect: false; + }): TweetStream; + sample10Stream(options?: Partial & { + autoConnect?: boolean; + }): PromiseOrType>; + /** + * Returns a list of recent compliance jobs. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs + */ + complianceJobs(options: BatchComplianceSearchV2Params): Promise; + /** + * Get a single compliance job with the specified ID. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs-id + */ + complianceJob(jobId: string): Promise; + /** + * Creates a new compliance job for Tweet IDs or user IDs, send your file, await result and parse it into an array. + * You can run one batch job at a time. Returns the created job, but **not the job result!**. + * + * You can obtain the result (**after job is completed**) with `.complianceJobResult`. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + sendComplianceJob(jobParams: BatchComplianceV2Params): Promise; + /** + * Get the result of a running or completed job, obtained through `.complianceJob`, `.complianceJobs` or `.sendComplianceJob`. + * If job is still running (`in_progress`), it will await until job is completed. **This could be quite long!** + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + complianceJobResult(job: BatchComplianceJobV2): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.js b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.js new file mode 100644 index 0000000..d873ee4 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.read.js @@ -0,0 +1,632 @@ +import TwitterApiSubClient from '../client.subclient'; +import { API_V2_PREFIX } from '../globals'; +import { TweetSearchAllV2Paginator, TweetSearchRecentV2Paginator, TweetUserMentionTimelineV2Paginator, TweetUserTimelineV2Paginator, TweetV2UserLikedTweetsPaginator, UserOwnedListsV2Paginator, UserListMembershipsV2Paginator, UserListFollowedV2Paginator, TweetV2ListTweetsPaginator, TweetBookmarksTimelineV2Paginator, QuotedTweetsTimelineV2Paginator, TweetHomeTimelineV2Paginator, } from '../paginators'; +import TwitterApiv2LabsReadOnly from '../v2-labs/client.v2.labs.read'; +import { TweetLikingUsersV2Paginator, TweetRetweetersUsersV2Paginator, UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator, UserListFollowersV2Paginator, UserListMembersV2Paginator, UserMutingUsersV2Paginator } from '../paginators/user.paginator.v2'; +import { isTweetStreamV2ErrorPayload } from '../helpers'; +import { ConversationDMTimelineV2Paginator, FullDMTimelineV2Paginator, OneToOneDMTimelineV2Paginator } from '../paginators/dm.paginator.v2'; +/** + * Base Twitter v2 client with only read right. + */ +export default class TwitterApiv2ReadOnly extends TwitterApiSubClient { + constructor() { + super(...arguments); + this._prefix = API_V2_PREFIX; + } + /* Sub-clients */ + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new TwitterApiv2LabsReadOnly(this); + } + async search(queryOrOptions, options = {}) { + const queryParams = typeof queryOrOptions === 'string' ? + { ...options, query: queryOrOptions } : + { ...queryOrOptions }; + const initialRq = await this.get('tweets/search/recent', queryParams, { fullResponse: true }); + return new TweetSearchRecentV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all + */ + async searchAll(query, options = {}) { + const queryParams = { ...options, query }; + const initialRq = await this.get('tweets/search/all', queryParams, { fullResponse: true }); + return new TweetSearchAllV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams, + }); + } + /** + * Returns a variety of information about a single Tweet specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + singleTweet(tweetId, options = {}) { + return this.get('tweets/:id', options, { params: { id: tweetId } }); + } + /** + * Returns a variety of information about tweets specified by list of IDs. + * https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + tweets(tweetIds, options = {}) { + return this.get('tweets', { ids: tweetIds, ...options }); + } + /** + * The recent Tweet counts endpoint returns count of Tweets from the last seven days that match a search query. + * OAuth2 Bearer auth only. + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + */ + tweetCountRecent(query, options = {}) { + return this.get('tweets/counts/recent', { query, ...options }); + } + /** + * This endpoint is only available to those users who have been approved for the Academic Research product track. + * The full-archive search endpoint returns the complete history of public Tweets matching a search query; + * since the first Tweet was created March 26, 2006. + * OAuth2 Bearer auth only. + * **This endpoint has pagination, yet it is not supported by bundled paginators. Use `next_token` to fetch next page.** + * https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + */ + tweetCountAll(query, options = {}) { + return this.get('tweets/counts/all', { query, ...options }); + } + async tweetRetweetedBy(tweetId, options = {}) { + const { asPaginator, ...parameters } = options; + const initialRq = await this.get('tweets/:id/retweeted_by', parameters, { + fullResponse: true, + params: { id: tweetId }, + }); + if (!asPaginator) { + return initialRq.data; + } + return new TweetRetweetersUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: { id: tweetId }, + }); + } + async tweetLikedBy(tweetId, options = {}) { + const { asPaginator, ...parameters } = options; + const initialRq = await this.get('tweets/:id/liking_users', parameters, { + fullResponse: true, + params: { id: tweetId }, + }); + if (!asPaginator) { + return initialRq.data; + } + return new TweetLikingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: { id: tweetId }, + }); + } + /** + * Allows you to retrieve a collection of the most recent Tweets and Retweets posted by you and users you follow, also known as home timeline. + * This endpoint returns up to the last 3200 Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological + * + * OAuth 2 scopes: `tweet.read` `users.read` + */ + async homeTimeline(options = {}) { + const meUser = await this.getCurrentUserV2Object(); + const initialRq = await this.get('users/:id/timelines/reverse_chronological', options, { + fullResponse: true, + params: { id: meUser.data.id }, + }); + return new TweetHomeTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: meUser.data.id }, + }); + } + /** + * Returns Tweets composed by a single user, specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, the most recent 3,200 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + */ + async userTimeline(userId, options = {}) { + const initialRq = await this.get('users/:id/tweets', options, { + fullResponse: true, + params: { id: userId }, + }); + return new TweetUserTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: userId }, + }); + } + /** + * Returns Tweets mentioning a single user specified by the requested user ID. + * By default, the most recent ten Tweets are returned per request. + * Using pagination, up to the most recent 800 Tweets can be retrieved. + * https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions + */ + async userMentionTimeline(userId, options = {}) { + const initialRq = await this.get('users/:id/mentions', options, { + fullResponse: true, + params: { id: userId }, + }); + return new TweetUserMentionTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: userId }, + }); + } + /** + * Returns Quote Tweets for a Tweet specified by the requested Tweet ID. + * https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets + * + * OAuth2 scopes: `users.read` `tweet.read` + */ + async quotes(tweetId, options = {}) { + const initialRq = await this.get('tweets/:id/quote_tweets', options, { + fullResponse: true, + params: { id: tweetId }, + }); + return new QuotedTweetsTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: tweetId }, + }); + } + /* Bookmarks */ + /** + * Allows you to get information about a authenticated user’s 800 most recent bookmarked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.read` + */ + async bookmarks(options = {}) { + const user = await this.getCurrentUserV2Object(); + const initialRq = await this.get('users/:id/bookmarks', options, { + fullResponse: true, + params: { id: user.data.id }, + }); + return new TweetBookmarksTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: options, + sharedParams: { id: user.data.id }, + }); + } + /* Users */ + /** + * Returns information about an authorized user. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me + * + * OAuth2 scopes: `tweet.read` & `users.read` + */ + me(options = {}) { + return this.get('users/me', options); + } + /** + * Returns a variety of information about a single user specified by the requested ID. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-id + */ + user(userId, options = {}) { + return this.get('users/:id', options, { params: { id: userId } }); + } + /** + * Returns a variety of information about one or more users specified by the requested IDs. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users + */ + users(userIds, options = {}) { + const ids = Array.isArray(userIds) ? userIds.join(',') : userIds; + return this.get('users', { ...options, ids }); + } + /** + * Returns a variety of information about a single user specified by their username. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username + */ + userByUsername(username, options = {}) { + return this.get('users/by/username/:username', options, { params: { username } }); + } + /** + * Returns a variety of information about one or more users specified by their usernames. + * https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * OAuth2 scope: `users.read`, `tweet.read` + */ + usersByUsernames(usernames, options = {}) { + usernames = Array.isArray(usernames) ? usernames.join(',') : usernames; + return this.get('users/by', { ...options, usernames }); + } + async followers(userId, options = {}) { + const { asPaginator, ...parameters } = options; + const params = { id: userId }; + if (!asPaginator) { + return this.get('users/:id/followers', parameters, { params }); + } + const initialRq = await this.get('users/:id/followers', parameters, { fullResponse: true, params }); + return new UserFollowersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: params, + }); + } + async following(userId, options = {}) { + const { asPaginator, ...parameters } = options; + const params = { id: userId }; + if (!asPaginator) { + return this.get('users/:id/following', parameters, { params }); + } + const initialRq = await this.get('users/:id/following', parameters, { fullResponse: true, params }); + return new UserFollowingV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: parameters, + sharedParams: params, + }); + } + /** + * Allows you to get information about a user’s liked Tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + */ + async userLikedTweets(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/liked_tweets', options, { fullResponse: true, params }); + return new TweetV2UserLikedTweetsPaginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are blocked by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + */ + async userBlockingUsers(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/blocking', options, { fullResponse: true, params }); + return new UserBlockingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are muted by the authenticating user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting + */ + async userMutingUsers(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/muting', options, { fullResponse: true, params }); + return new UserMutingUsersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Lists */ + /** + * Returns the details of a specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + */ + list(id, options = {}) { + return this.get('lists/:id', options, { params: { id } }); + } + /** + * Returns all Lists owned by the specified user. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists + */ + async listsOwned(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/owned_lists', options, { fullResponse: true, params }); + return new UserOwnedListsV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns all Lists a specified user is a member of. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-users-id-list_memberships + */ + async listMemberships(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/list_memberships', options, { fullResponse: true, params }); + return new UserListMembershipsV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns all Lists a specified user follows. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-users-id-followed_lists + */ + async listFollowed(userId, options = {}) { + const params = { id: userId }; + const initialRq = await this.get('users/:id/followed_lists', options, { fullResponse: true, params }); + return new UserListFollowedV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of Tweets from the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-tweets/api-reference/get-lists-id-tweets + */ + async listTweets(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/tweets', options, { fullResponse: true, params }); + return new TweetV2ListTweetsPaginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are members of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-members/api-reference/get-lists-id-members + */ + async listMembers(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/members', options, { fullResponse: true, params }); + return new UserListMembersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of users who are followers of the specified List. + * https://developer.twitter.com/en/docs/twitter-api/lists/list-follows/api-reference/get-lists-id-followers + */ + async listFollowers(listId, options = {}) { + const params = { id: listId }; + const initialRq = await this.get('lists/:id/followers', options, { fullResponse: true, params }); + return new UserListFollowersV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Direct messages */ + /** + * Returns a list of Direct Messages for the authenticated user, both sent and received. + * Direct Message events are returned in reverse chronological order. + * Supports retrieving events from the previous 30 days. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_events + */ + async listDmEvents(options = {}) { + const initialRq = await this.get('dm_events', options, { fullResponse: true }); + return new FullDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + }); + } + /** + * Returns a list of Direct Messages (DM) events within a 1-1 conversation with the user specified in the participant_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + async listDmEventsWithParticipant(participantId, options = {}) { + const params = { participant_id: participantId }; + const initialRq = await this.get('dm_conversations/with/:participant_id/dm_events', options, { fullResponse: true, params }); + return new OneToOneDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /** + * Returns a list of Direct Messages within a conversation specified in the dm_conversation_id path parameter. + * Messages are returned in reverse chronological order. + * + * OAuth 2 scopes: `dm.read`, `tweet.read`, `user.read` + * + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm_conversations-dm_conversation_id-dm_events + */ + async listDmEventsOfConversation(dmConversationId, options = {}) { + const params = { dm_conversation_id: dmConversationId }; + const initialRq = await this.get('dm_conversations/:dm_conversation_id/dm_events', options, { fullResponse: true, params }); + return new ConversationDMTimelineV2Paginator({ + realData: initialRq.data, + rateLimit: initialRq.rateLimit, + instance: this, + queryParams: { ...options }, + sharedParams: params, + }); + } + /* Spaces */ + /** + * Get a single space by ID. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + space(spaceId, options = {}) { + return this.get('spaces/:id', options, { params: { id: spaceId } }); + } + /** + * Get spaces using their IDs. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaces(spaceIds, options = {}) { + return this.get('spaces', { ids: spaceIds, ...options }); + } + /** + * Get spaces using their creator user ID(s). (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spacesByCreators(creatorIds, options = {}) { + return this.get('spaces/by/creator_ids', { user_ids: creatorIds, ...options }); + } + /** + * Search through spaces using multiple params. (no pagination available) + * https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search + */ + searchSpaces(options) { + return this.get('spaces/search', options); + } + /** + * Returns a list of user who purchased a ticket to the requested Space. + * You must authenticate the request using the Access Token of the creator of the requested Space. + * + * **OAuth 2.0 Access Token required** + * + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-buyers + * + * OAuth2 scopes: `tweet.read`, `users.read`, `space.read`. + */ + spaceBuyers(spaceId, options = {}) { + return this.get('spaces/:id/buyers', options, { params: { id: spaceId } }); + } + /** + * Returns Tweets shared in the requested Spaces. + * https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-tweets + * + * OAuth2 scope: `users.read`, `tweet.read`, `space.read` + */ + spaceTweets(spaceId, options = {}) { + return this.get('spaces/:id/tweets', options, { params: { id: spaceId } }); + } + searchStream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/search/stream', options, { payloadIsError: isTweetStreamV2ErrorPayload, autoConnect }); + } + /** + * Return a list of rules currently active on the streaming endpoint, either as a list or individually. + * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules + */ + streamRules(options = {}) { + return this.get('tweets/search/stream/rules', options); + } + updateStreamRules(options, query = {}) { + return this.post('tweets/search/stream/rules', options, { query }); + } + sampleStream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/sample/stream', options, { payloadIsError: isTweetStreamV2ErrorPayload, autoConnect }); + } + sample10Stream({ autoConnect, ...options } = {}) { + return this.getStream('tweets/sample10/stream', options, { payloadIsError: isTweetStreamV2ErrorPayload, autoConnect }); + } + /* Batch compliance */ + /** + * Returns a list of recent compliance jobs. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs + */ + complianceJobs(options) { + return this.get('compliance/jobs', options); + } + /** + * Get a single compliance job with the specified ID. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs-id + */ + complianceJob(jobId) { + return this.get('compliance/jobs/:id', undefined, { params: { id: jobId } }); + } + /** + * Creates a new compliance job for Tweet IDs or user IDs, send your file, await result and parse it into an array. + * You can run one batch job at a time. Returns the created job, but **not the job result!**. + * + * You can obtain the result (**after job is completed**) with `.complianceJobResult`. + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + async sendComplianceJob(jobParams) { + const job = await this.post('compliance/jobs', { type: jobParams.type, name: jobParams.name }); + // Send the IDs + const rawIdsBody = jobParams.ids instanceof Buffer ? jobParams.ids : Buffer.from(jobParams.ids.join('\n')); + // Upload the IDs + await this.put(job.data.upload_url, rawIdsBody, { + forceBodyMode: 'raw', + enableAuth: false, + headers: { 'Content-Type': 'text/plain' }, + prefix: '', + }); + return job; + } + /** + * Get the result of a running or completed job, obtained through `.complianceJob`, `.complianceJobs` or `.sendComplianceJob`. + * If job is still running (`in_progress`), it will await until job is completed. **This could be quite long!** + * https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + */ + async complianceJobResult(job) { + let runningJob = job; + while (runningJob.status !== 'complete') { + if (runningJob.status === 'expired' || runningJob.status === 'failed') { + throw new Error('Job failed to be completed.'); + } + await new Promise(resolve => setTimeout(resolve, 3500)); + runningJob = (await this.complianceJob(job.id)).data; + } + // Download and parse result + const result = await this.get(job.download_url, undefined, { + enableAuth: false, + prefix: '', + }); + return result + .trim() + .split('\n') + .filter(line => line) + .map(line => JSON.parse(line)); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.d.ts b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.d.ts new file mode 100644 index 0000000..41c8dbb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.d.ts @@ -0,0 +1,204 @@ +import TwitterApiv2ReadOnly from './client.v2.read'; +import type { ListCreateV2Params, ListCreateV2Result, ListDeleteV2Result, ListFollowV2Result, ListMemberV2Result, ListPinV2Result, ListUpdateV2Params, ListUpdateV2Result, TweetV2DeleteTweetResult, SendTweetV2Params, TweetV2HideReplyResult, TweetV2LikeResult, TweetV2PostTweetResult, TweetV2RetweetResult, UserV2BlockResult, UserV2FollowResult, UserV2MuteResult, UserV2UnfollowResult, TweetV2BookmarkResult } from '../types'; +import TwitterApiv2LabsReadWrite from '../v2-labs/client.v2.labs.write'; +import { CreateDMConversationParams, PostDMInConversationParams, PostDMInConversationResult } from '../types/v2/dm.v2.types'; +/** + * Base Twitter v2 client with read/write rights. + */ +export default class TwitterApiv2ReadWrite extends TwitterApiv2ReadOnly { + protected _prefix: string; + protected _labs?: TwitterApiv2LabsReadWrite; + /** + * Get a client with only read rights. + */ + get readOnly(): TwitterApiv2ReadOnly; + /** + * Get a client for v2 labs endpoints. + */ + get labs(): TwitterApiv2LabsReadWrite; + /** + * Hides or unhides a reply to a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/hide-replies/api-reference/put-tweets-id-hidden + */ + hideReply(tweetId: string, makeHidden: boolean): Promise; + /** + * Causes the user ID identified in the path parameter to Like the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-user_id-likes + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + like(loggedUserId: string, targetTweetId: string): Promise; + /** + * Allows a user or authenticated user ID to unlike a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not liking the Tweet or have already unliked the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unlike(loggedUserId: string, targetTweetId: string): Promise; + /** + * Causes the user ID identified in the path parameter to Retweet the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + retweet(loggedUserId: string, targetTweetId: string): Promise; + /** + * Allows a user or authenticated user ID to remove the Retweet of a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not Retweeting the Tweet or have already removed the Retweet of. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unretweet(loggedUserId: string, targetTweetId: string): Promise; + /** + * Creates a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + tweet(status: string, payload?: Partial): Promise; + tweet(payload: SendTweetV2Params): Promise; + /** + * Reply to a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + reply(status: string, toTweetId: string, payload?: Partial): Promise; + /** + * Quote an existing Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + quote(status: string, quotedTweetId: string, payload?: Partial): Promise; + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + tweetThread(tweets: (SendTweetV2Params | string)[]): Promise; + /** + * Allows a user or authenticated user ID to delete a Tweet + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + */ + deleteTweet(tweetId: string): Promise; + /** + * Causes the user ID of an authenticated user identified in the path parameter to Bookmark the target Tweet provided in the request body. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + bookmark(tweetId: string): Promise; + /** + * Allows a user or authenticated user ID to remove a Bookmark of a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + deleteBookmark(tweetId: string): Promise; + /** + * Allows a user ID to follow another user. + * If the target user does not have public Tweets, this endpoint will send a follow request. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/post-users-source_user_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + follow(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows a user ID to unfollow another user. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unfollow(loggedUserId: string, targetUserId: string): Promise; + /** + * Causes the user (in the path) to block the target user. + * The user (in the path) must match the user context authorizing the request. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID; you can obtain it through v1.1 API. + */ + block(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows a user or authenticated user ID to unblock another user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unblock(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows an authenticated user ID to mute the target user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + mute(loggedUserId: string, targetUserId: string): Promise; + /** + * Allows an authenticated user ID to unmute the target user. + * The request succeeds with no action when the user sends a request to a user they're not muting or have already unmuted. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unmute(loggedUserId: string, targetUserId: string): Promise; + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists + */ + createList(options: ListCreateV2Params): Promise; + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/put-lists-id + */ + updateList(listId: string, options?: ListUpdateV2Params): Promise; + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id + */ + removeList(listId: string): Promise; + /** + * Adds a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists-id-members + */ + addListMember(listId: string, userId: string): Promise; + /** + * Remember a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id-members-user_id + */ + removeListMember(listId: string, userId: string): Promise; + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-followed-lists + */ + subscribeToList(loggedUserId: string, listId: string): Promise; + /** + * Unsubscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-followed-lists-list_id + */ + unsubscribeOfList(loggedUserId: string, listId: string): Promise; + /** + * Enables the authenticated user to pin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-pinned-lists + */ + pinList(loggedUserId: string, listId: string): Promise; + /** + * Enables the authenticated user to unpin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-pinned-lists-list_id + */ + unpinList(loggedUserId: string, listId: string): Promise; + /** + * Creates a Direct Message on behalf of an authenticated user, and adds it to the specified conversation. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-dm_conversation_id-messages + */ + sendDmInConversation(conversationId: string, message: PostDMInConversationParams): Promise; + /** + * Creates a one-to-one Direct Message and adds it to the one-to-one conversation. + * This method either creates a new one-to-one conversation or retrieves the current conversation and adds the Direct Message to it. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-with-participant_id-messages + */ + sendDmToParticipant(participantId: string, message: PostDMInConversationParams): Promise; + /** + * Creates a new group conversation and adds a Direct Message to it on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations + */ + createDmConversation(options: CreateDMConversationParams): Promise; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.js b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.js new file mode 100644 index 0000000..8d2b878 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/client.v2.write.js @@ -0,0 +1,313 @@ +import { API_V2_PREFIX } from '../globals'; +import TwitterApiv2ReadOnly from './client.v2.read'; +import TwitterApiv2LabsReadWrite from '../v2-labs/client.v2.labs.write'; +/** + * Base Twitter v2 client with read/write rights. + */ +export default class TwitterApiv2ReadWrite extends TwitterApiv2ReadOnly { + constructor() { + super(...arguments); + this._prefix = API_V2_PREFIX; + } + /* Sub-clients */ + /** + * Get a client with only read rights. + */ + get readOnly() { + return this; + } + /** + * Get a client for v2 labs endpoints. + */ + get labs() { + if (this._labs) + return this._labs; + return this._labs = new TwitterApiv2LabsReadWrite(this); + } + /* Tweets */ + /** + * Hides or unhides a reply to a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/hide-replies/api-reference/put-tweets-id-hidden + */ + hideReply(tweetId, makeHidden) { + return this.put('tweets/:id/hidden', { hidden: makeHidden }, { params: { id: tweetId } }); + } + /** + * Causes the user ID identified in the path parameter to Like the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-user_id-likes + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + like(loggedUserId, targetTweetId) { + return this.post('users/:id/likes', { tweet_id: targetTweetId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to unlike a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not liking the Tweet or have already unliked the Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unlike(loggedUserId, targetTweetId) { + return this.delete('users/:id/likes/:tweet_id', undefined, { + params: { id: loggedUserId, tweet_id: targetTweetId }, + }); + } + /** + * Causes the user ID identified in the path parameter to Retweet the target Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + retweet(loggedUserId, targetTweetId) { + return this.post('users/:id/retweets', { tweet_id: targetTweetId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to remove the Retweet of a Tweet. + * The request succeeds with no action when the user sends a request to a user they're not Retweeting the Tweet or have already removed the Retweet of. + * https://developer.twitter.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unretweet(loggedUserId, targetTweetId) { + return this.delete('users/:id/retweets/:tweet_id', undefined, { + params: { id: loggedUserId, tweet_id: targetTweetId }, + }); + } + tweet(status, payload = {}) { + if (typeof status === 'object') { + payload = status; + } + else { + payload = { text: status, ...payload }; + } + return this.post('tweets', payload); + } + /** + * Reply to a Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + reply(status, toTweetId, payload = {}) { + var _a; + const reply = { in_reply_to_tweet_id: toTweetId, ...(_a = payload.reply) !== null && _a !== void 0 ? _a : {} }; + return this.post('tweets', { text: status, ...payload, reply }); + } + /** + * Quote an existing Tweet on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + quote(status, quotedTweetId, payload = {}) { + return this.tweet(status, { ...payload, quote_tweet_id: quotedTweetId }); + } + /** + * Post a series of tweets. + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + */ + async tweetThread(tweets) { + var _a, _b; + const postedTweets = []; + for (const tweet of tweets) { + // Retrieve the last sent tweet + const lastTweet = postedTweets.length ? postedTweets[postedTweets.length - 1] : null; + // Build the tweet query params + const queryParams = { ...(typeof tweet === 'string' ? ({ text: tweet }) : tweet) }; + // Reply to an existing tweet if needed + const inReplyToId = lastTweet ? lastTweet.data.id : (_a = queryParams.reply) === null || _a === void 0 ? void 0 : _a.in_reply_to_tweet_id; + const status = (_b = queryParams.text) !== null && _b !== void 0 ? _b : ''; + if (inReplyToId) { + postedTweets.push(await this.reply(status, inReplyToId, queryParams)); + } + else { + postedTweets.push(await this.tweet(status, queryParams)); + } + } + return postedTweets; + } + /** + * Allows a user or authenticated user ID to delete a Tweet + * https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + */ + deleteTweet(tweetId) { + return this.delete('tweets/:id', undefined, { + params: { + id: tweetId, + }, + }); + } + /* Bookmarks */ + /** + * Causes the user ID of an authenticated user identified in the path parameter to Bookmark the target Tweet provided in the request body. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + async bookmark(tweetId) { + const user = await this.getCurrentUserV2Object(); + return this.post('users/:id/bookmarks', { tweet_id: tweetId }, { params: { id: user.data.id } }); + } + /** + * Allows a user or authenticated user ID to remove a Bookmark of a Tweet. + * https://developer.twitter.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id + * + * OAuth2 scopes: `users.read` `tweet.read` `bookmark.write` + */ + async deleteBookmark(tweetId) { + const user = await this.getCurrentUserV2Object(); + return this.delete('users/:id/bookmarks/:tweet_id', undefined, { params: { id: user.data.id, tweet_id: tweetId } }); + } + /* Users */ + /** + * Allows a user ID to follow another user. + * If the target user does not have public Tweets, this endpoint will send a follow request. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/post-users-source_user_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + follow(loggedUserId, targetUserId) { + return this.post('users/:id/following', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user ID to unfollow another user. + * https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following + * + * OAuth2 scope: `follows.write` + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unfollow(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/following/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /** + * Causes the user (in the path) to block the target user. + * The user (in the path) must match the user context authorizing the request. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID; you can obtain it through v1.1 API. + */ + block(loggedUserId, targetUserId) { + return this.post('users/:id/blocking', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows a user or authenticated user ID to unblock another user. + * https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unblock(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/blocking/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /** + * Allows an authenticated user ID to mute the target user. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + mute(loggedUserId, targetUserId) { + return this.post('users/:id/muting', { target_user_id: targetUserId }, { params: { id: loggedUserId } }); + } + /** + * Allows an authenticated user ID to unmute the target user. + * The request succeeds with no action when the user sends a request to a user they're not muting or have already unmuted. + * https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting + * + * **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API. + */ + unmute(loggedUserId, targetUserId) { + return this.delete('users/:source_user_id/muting/:target_user_id', undefined, { + params: { source_user_id: loggedUserId, target_user_id: targetUserId }, + }); + } + /* Lists */ + /** + * Creates a new list for the authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists + */ + createList(options) { + return this.post('lists', options); + } + /** + * Updates the specified list. The authenticated user must own the list to be able to update it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/put-lists-id + */ + updateList(listId, options = {}) { + return this.put('lists/:id', options, { params: { id: listId } }); + } + /** + * Deletes the specified list. The authenticated user must own the list to be able to destroy it. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id + */ + removeList(listId) { + return this.delete('lists/:id', undefined, { params: { id: listId } }); + } + /** + * Adds a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists-id-members + */ + addListMember(listId, userId) { + return this.post('lists/:id/members', { user_id: userId }, { params: { id: listId } }); + } + /** + * Remember a member to a list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id-members-user_id + */ + removeListMember(listId, userId) { + return this.delete('lists/:id/members/:user_id', undefined, { params: { id: listId, user_id: userId } }); + } + /** + * Subscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-followed-lists + */ + subscribeToList(loggedUserId, listId) { + return this.post('users/:id/followed_lists', { list_id: listId }, { params: { id: loggedUserId } }); + } + /** + * Unsubscribes the authenticated user to the specified list. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-followed-lists-list_id + */ + unsubscribeOfList(loggedUserId, listId) { + return this.delete('users/:id/followed_lists/:list_id', undefined, { params: { id: loggedUserId, list_id: listId } }); + } + /** + * Enables the authenticated user to pin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-users-id-pinned-lists + */ + pinList(loggedUserId, listId) { + return this.post('users/:id/pinned_lists', { list_id: listId }, { params: { id: loggedUserId } }); + } + /** + * Enables the authenticated user to unpin a List. + * https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-users-id-pinned-lists-list_id + */ + unpinList(loggedUserId, listId) { + return this.delete('users/:id/pinned_lists/:list_id', undefined, { params: { id: loggedUserId, list_id: listId } }); + } + /* Direct messages */ + /** + * Creates a Direct Message on behalf of an authenticated user, and adds it to the specified conversation. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-dm_conversation_id-messages + */ + sendDmInConversation(conversationId, message) { + return this.post('dm_conversations/:dm_conversation_id/messages', message, { params: { dm_conversation_id: conversationId } }); + } + /** + * Creates a one-to-one Direct Message and adds it to the one-to-one conversation. + * This method either creates a new one-to-one conversation or retrieves the current conversation and adds the Direct Message to it. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations-with-participant_id-messages + */ + sendDmToParticipant(participantId, message) { + return this.post('dm_conversations/with/:participant_id/messages', message, { params: { participant_id: participantId } }); + } + /** + * Creates a new group conversation and adds a Direct Message to it on behalf of an authenticated user. + * https://developer.twitter.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm_conversations + */ + createDmConversation(options) { + return this.post('dm_conversations', options); + } +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.d.ts b/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.d.ts new file mode 100644 index 0000000..639f9eb --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.d.ts @@ -0,0 +1,82 @@ +import type { ApiV2Includes, ListV2, SpaceV2, TweetV2, UserV2 } from '../types'; +export declare type TTwitterV2IncludesResult = { + includes?: ApiV2Includes; +}; +/** + * Provide helpers for `.includes` of a v2 API result. + * Needed expansions for a method to work are specified (*`like this`*). + */ +export declare class TwitterV2IncludesHelper implements ApiV2Includes { + protected result: TTwitterV2IncludesResult; + constructor(result: TTwitterV2IncludesResult); + get tweets(): TweetV2[]; + static tweets(result: TTwitterV2IncludesResult): TweetV2[]; + tweetById(id: string): TweetV2 | undefined; + static tweetById(result: TTwitterV2IncludesResult, id: string): TweetV2 | undefined; + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + retweet(tweet: TweetV2): TweetV2 | undefined; + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + static retweet(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + quote(tweet: TweetV2): TweetV2 | undefined; + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + static quote(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + repliedTo(tweet: TweetV2): TweetV2 | undefined; + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + static repliedTo(result: TTwitterV2IncludesResult, tweet: TweetV2): TweetV2 | undefined; + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + author(tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + static author(result: TTwitterV2IncludesResult, tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + repliedToAuthor(tweet: TweetV2): UserV2 | undefined; + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + static repliedToAuthor(result: TTwitterV2IncludesResult, tweet: TweetV2): UserV2 | undefined; + get users(): UserV2[]; + static users(result: TTwitterV2IncludesResult): UserV2[]; + userById(id: string): UserV2 | undefined; + static userById(result: TTwitterV2IncludesResult, id: string): UserV2 | undefined; + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + pinnedTweet(user: UserV2): TweetV2 | undefined; + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + static pinnedTweet(result: TTwitterV2IncludesResult, user: UserV2): TweetV2 | undefined; + get media(): import("../types").MediaObjectV2[]; + static media(result: TTwitterV2IncludesResult): import("../types").MediaObjectV2[]; + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + medias(tweet: TweetV2): import("../types").MediaObjectV2[]; + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + static medias(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").MediaObjectV2[]; + get polls(): import("../types").PollV2[]; + static polls(result: TTwitterV2IncludesResult): import("../types").PollV2[]; + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + poll(tweet: TweetV2): import("../types").PollV2 | undefined; + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + static poll(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").PollV2 | undefined; + get places(): import("../types").PlaceV2[]; + static places(result: TTwitterV2IncludesResult): import("../types").PlaceV2[]; + /** Place associated with the given tweet (*`geo.place_id`*) */ + place(tweet: TweetV2): import("../types").PlaceV2 | undefined; + /** Place associated with the given tweet (*`geo.place_id`*) */ + static place(result: TTwitterV2IncludesResult, tweet: TweetV2): import("../types").PlaceV2 | undefined; + /** List owner of the given list (*`owner_id`*) */ + listOwner(list: ListV2): UserV2 | undefined; + /** List owner of the given list (*`owner_id`*) */ + static listOwner(result: TTwitterV2IncludesResult, list: ListV2): UserV2 | undefined; + /** Creator of the given space (*`creator_id`*) */ + spaceCreator(space: SpaceV2): UserV2 | undefined; + /** Creator of the given space (*`creator_id`*) */ + static spaceCreator(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2 | undefined; + /** Current hosts of the given space (*`host_ids`*) */ + spaceHosts(space: SpaceV2): UserV2[]; + /** Current hosts of the given space (*`host_ids`*) */ + static spaceHosts(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; + /** Current speakers of the given space (*`speaker_ids`*) */ + spaceSpeakers(space: SpaceV2): UserV2[]; + /** Current speakers of the given space (*`speaker_ids`*) */ + static spaceSpeakers(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; + /** Current invited users of the given space (*`invited_user_ids`*) */ + spaceInvitedUsers(space: SpaceV2): UserV2[]; + /** Current invited users of the given space (*`invited_user_ids`*) */ + static spaceInvitedUsers(result: TTwitterV2IncludesResult, space: SpaceV2): UserV2[]; +} diff --git a/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.js b/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.js new file mode 100644 index 0000000..95d2402 --- /dev/null +++ b/node_modules/twitter-api-v2/dist/esm/v2/includes.v2.helper.js @@ -0,0 +1,207 @@ +/** + * Provide helpers for `.includes` of a v2 API result. + * Needed expansions for a method to work are specified (*`like this`*). + */ +export class TwitterV2IncludesHelper { + constructor(result) { + this.result = result; + } + /* Tweets */ + get tweets() { + return TwitterV2IncludesHelper.tweets(this.result); + } + static tweets(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.tweets) !== null && _b !== void 0 ? _b : []; + } + tweetById(id) { + return TwitterV2IncludesHelper.tweetById(this.result, id); + } + static tweetById(result, id) { + return this.tweets(result).find(tweet => tweet.id === id); + } + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + retweet(tweet) { + return TwitterV2IncludesHelper.retweet(this.result, tweet); + } + /** Retweet associated with the given tweet (*`referenced_tweets.id`*) */ + static retweet(result, tweet) { + var _a; + const retweetIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'retweeted') + .map(ref => ref.id); + return this.tweets(result).find(t => retweetIds.includes(t.id)); + } + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + quote(tweet) { + return TwitterV2IncludesHelper.quote(this.result, tweet); + } + /** Quoted tweet associated with the given tweet (*`referenced_tweets.id`*) */ + static quote(result, tweet) { + var _a; + const quoteIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'quoted') + .map(ref => ref.id); + return this.tweets(result).find(t => quoteIds.includes(t.id)); + } + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + repliedTo(tweet) { + return TwitterV2IncludesHelper.repliedTo(this.result, tweet); + } + /** Tweet whose has been answered by the given tweet (*`referenced_tweets.id`*) */ + static repliedTo(result, tweet) { + var _a; + const repliesIds = ((_a = tweet.referenced_tweets) !== null && _a !== void 0 ? _a : []) + .filter(ref => ref.type === 'replied_to') + .map(ref => ref.id); + return this.tweets(result).find(t => repliesIds.includes(t.id)); + } + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + author(tweet) { + return TwitterV2IncludesHelper.author(this.result, tweet); + } + /** Tweet author user object of the given tweet (*`author_id`* or *`referenced_tweets.id.author_id`*) */ + static author(result, tweet) { + const authorId = tweet.author_id; + return authorId ? this.users(result).find(u => u.id === authorId) : undefined; + } + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + repliedToAuthor(tweet) { + return TwitterV2IncludesHelper.repliedToAuthor(this.result, tweet); + } + /** Tweet author user object of the tweet answered by the given tweet (*`in_reply_to_user_id`*) */ + static repliedToAuthor(result, tweet) { + const inReplyUserId = tweet.in_reply_to_user_id; + return inReplyUserId ? this.users(result).find(u => u.id === inReplyUserId) : undefined; + } + /* Users */ + get users() { + return TwitterV2IncludesHelper.users(this.result); + } + static users(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.users) !== null && _b !== void 0 ? _b : []; + } + userById(id) { + return TwitterV2IncludesHelper.userById(this.result, id); + } + static userById(result, id) { + return this.users(result).find(u => u.id === id); + } + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + pinnedTweet(user) { + return TwitterV2IncludesHelper.pinnedTweet(this.result, user); + } + /** Pinned tweet of the given user (*`pinned_tweet_id`*) */ + static pinnedTweet(result, user) { + return user.pinned_tweet_id ? this.tweets(result).find(t => t.id === user.pinned_tweet_id) : undefined; + } + /* Medias */ + get media() { + return TwitterV2IncludesHelper.media(this.result); + } + static media(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.media) !== null && _b !== void 0 ? _b : []; + } + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + medias(tweet) { + return TwitterV2IncludesHelper.medias(this.result, tweet); + } + /** Medias associated with the given tweet (*`attachments.media_keys`*) */ + static medias(result, tweet) { + var _a, _b; + const keys = (_b = (_a = tweet.attachments) === null || _a === void 0 ? void 0 : _a.media_keys) !== null && _b !== void 0 ? _b : []; + return this.media(result).filter(m => keys.includes(m.media_key)); + } + /* Polls */ + get polls() { + return TwitterV2IncludesHelper.polls(this.result); + } + static polls(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.polls) !== null && _b !== void 0 ? _b : []; + } + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + poll(tweet) { + return TwitterV2IncludesHelper.poll(this.result, tweet); + } + /** Poll associated with the given tweet (*`attachments.poll_ids`*) */ + static poll(result, tweet) { + var _a, _b; + const pollIds = (_b = (_a = tweet.attachments) === null || _a === void 0 ? void 0 : _a.poll_ids) !== null && _b !== void 0 ? _b : []; + if (pollIds.length) { + const pollId = pollIds[0]; + return this.polls(result).find(p => p.id === pollId); + } + return undefined; + } + /* Places */ + get places() { + return TwitterV2IncludesHelper.places(this.result); + } + static places(result) { + var _a, _b; + return (_b = (_a = result.includes) === null || _a === void 0 ? void 0 : _a.places) !== null && _b !== void 0 ? _b : []; + } + /** Place associated with the given tweet (*`geo.place_id`*) */ + place(tweet) { + return TwitterV2IncludesHelper.place(this.result, tweet); + } + /** Place associated with the given tweet (*`geo.place_id`*) */ + static place(result, tweet) { + var _a; + const placeId = (_a = tweet.geo) === null || _a === void 0 ? void 0 : _a.place_id; + return placeId ? this.places(result).find(p => p.id === placeId) : undefined; + } + /* Lists */ + /** List owner of the given list (*`owner_id`*) */ + listOwner(list) { + return TwitterV2IncludesHelper.listOwner(this.result, list); + } + /** List owner of the given list (*`owner_id`*) */ + static listOwner(result, list) { + const creatorId = list.owner_id; + return creatorId ? this.users(result).find(p => p.id === creatorId) : undefined; + } + /* Spaces */ + /** Creator of the given space (*`creator_id`*) */ + spaceCreator(space) { + return TwitterV2IncludesHelper.spaceCreator(this.result, space); + } + /** Creator of the given space (*`creator_id`*) */ + static spaceCreator(result, space) { + const creatorId = space.creator_id; + return creatorId ? this.users(result).find(p => p.id === creatorId) : undefined; + } + /** Current hosts of the given space (*`host_ids`*) */ + spaceHosts(space) { + return TwitterV2IncludesHelper.spaceHosts(this.result, space); + } + /** Current hosts of the given space (*`host_ids`*) */ + static spaceHosts(result, space) { + var _a; + const hostIds = (_a = space.host_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => hostIds.includes(u.id)); + } + /** Current speakers of the given space (*`speaker_ids`*) */ + spaceSpeakers(space) { + return TwitterV2IncludesHelper.spaceSpeakers(this.result, space); + } + /** Current speakers of the given space (*`speaker_ids`*) */ + static spaceSpeakers(result, space) { + var _a; + const speakerIds = (_a = space.speaker_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => speakerIds.includes(u.id)); + } + /** Current invited users of the given space (*`invited_user_ids`*) */ + spaceInvitedUsers(space) { + return TwitterV2IncludesHelper.spaceInvitedUsers(this.result, space); + } + /** Current invited users of the given space (*`invited_user_ids`*) */ + static spaceInvitedUsers(result, space) { + var _a; + const invitedUserIds = (_a = space.invited_user_ids) !== null && _a !== void 0 ? _a : []; + return this.users(result).filter(u => invitedUserIds.includes(u.id)); + } +} diff --git a/node_modules/twitter-api-v2/package.json b/node_modules/twitter-api-v2/package.json new file mode 100644 index 0000000..717cf94 --- /dev/null +++ b/node_modules/twitter-api-v2/package.json @@ -0,0 +1,59 @@ +{ + "name": "twitter-api-v2", + "version": "1.15.1", + "description": "Strongly typed, full-featured, light, versatile yet powerful Twitter API v1.1 and v2 client for Node.js.", + "main": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "types": "dist/esm/index.d.ts", + "keywords": [ + "twitter", + "api", + "typed", + "types", + "v2", + "v1.1" + ], + "scripts": { + "build": "npm run build:cjs && npm run build:esm", + "build:cjs": "tsc -b tsconfig.cjs.json", + "build:esm": "tsc -b tsconfig.esm.json", + "build-doc": "typedoc src/index.ts --out tsdocs", + "lint": "eslint --ext \".ts\" --ignore-path .gitignore .", + "mocha": "mocha -r ts-node/register --timeout 10000", + "test": "npm run mocha 'test/**/*.test.ts'", + "test-tweet": "npm run mocha 'test/tweet.*.test.ts'", + "test-user": "npm run mocha 'test/user.*.test.ts'", + "test-stream": "npm run mocha test/stream.test.ts", + "test-media": "npm run mocha test/media-upload.test.ts", + "test-auth": "npm run mocha test/auth.test.ts", + "test-dm": "npm run mocha test/dm.*.test.ts", + "test-list": "npm run mocha test/list.*.test.ts", + "test-space": "npm run mocha test/space.v2.test.ts", + "test-account": "npm run mocha test/account.*.test.ts", + "test-plugin": "npm run mocha test/plugin.test.ts", + "prepublish": "npm run build" + }, + "repository": "github:plhery/node-twitter-api-v2", + "author": "Paul-Louis Hery (https://twitter.com/plhery)", + "license": "Apache-2.0", + "files": [ + "dist" + ], + "devDependencies": { + "@types/chai": "^4.2.16", + "@types/mocha": "^10.0.1", + "@types/node": "^18.11.17", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "chai": "^4.3.4", + "dotenv": "^16.0.3", + "eslint": "^8.30.0", + "mocha": "^10.0.0", + "ts-node": "^10.9.1", + "typedoc": "^0.23.23", + "typescript": "^4.2.4" + }, + "bugs": { + "url": "https://github.com/plhery/node-twitter-api/issues" + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4c45eb4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "twitter_post", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "twitter_post", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "twitter-api-v2": "^1.15.1" + } + }, + "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/package.json b/package.json new file mode 100644 index 0000000..055dc94 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "twitter_post", + "version": "1.0.0", + "description": "action to post new releases on twitter", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/intelowlproject/twitter_post.git" + }, + "author": "Shivam Purohit", + "license": "ISC", + "bugs": { + "url": "https://github.com/intelowlproject/twitter_post/issues" + }, + "homepage": "https://github.com/intelowlproject/twitter_post#readme", + "dependencies": { + "twitter-api-v2": "^1.15.1" + } +} diff --git a/publish.py b/publish.py deleted file mode 100644 index 72f9fb5..0000000 --- a/publish.py +++ /dev/null @@ -1,19 +0,0 @@ -import tweepy -import os -import sys - -api_key = sys.argv[1] -api_key_secret = sys.argv[2] -access_token = sys.argv[3] -access_token_secret = sys.argv[4] -status = sys.argv[5] - -client = tweepy.Client( - consumer_key=api_key, - consumer_secret=api_key_secret, - access_token=access_token, - access_token_secret=access_token_secret -) - -tweet_content = status -client.create_tweet(text = tweet_content)