@traceryn/tiktok-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +276 -0
- package/engineRequirements.js +7 -0
- package/lib/ProxiflyProvider.d.ts +24 -0
- package/lib/ProxiflyProvider.d.ts.map +1 -0
- package/lib/ProxiflyProvider.js +112 -0
- package/lib/ProxiflyProvider.js.map +1 -0
- package/lib/client.d.ts +42 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +377 -0
- package/lib/client.js.map +1 -0
- package/lib/core/CacheManager.d.ts +13 -0
- package/lib/core/CacheManager.d.ts.map +1 -0
- package/lib/core/CacheManager.js +49 -0
- package/lib/core/CacheManager.js.map +1 -0
- package/lib/core/CircuitBreaker.d.ts +21 -0
- package/lib/core/CircuitBreaker.d.ts.map +1 -0
- package/lib/core/CircuitBreaker.js +64 -0
- package/lib/core/CircuitBreaker.js.map +1 -0
- package/lib/core/Proxymanager.d.ts +32 -0
- package/lib/core/Proxymanager.d.ts.map +1 -0
- package/lib/core/Proxymanager.js +129 -0
- package/lib/core/Proxymanager.js.map +1 -0
- package/lib/core/RateLimiter.d.ts +17 -0
- package/lib/core/RateLimiter.d.ts.map +1 -0
- package/lib/core/RateLimiter.js +53 -0
- package/lib/core/RateLimiter.js.map +1 -0
- package/lib/core/RequestQueue.d.ts +17 -0
- package/lib/core/RequestQueue.d.ts.map +1 -0
- package/lib/core/RequestQueue.js +51 -0
- package/lib/core/RequestQueue.js.map +1 -0
- package/lib/core/RetryHandler.d.ts +13 -0
- package/lib/core/RetryHandler.d.ts.map +1 -0
- package/lib/core/RetryHandler.js +37 -0
- package/lib/core/RetryHandler.js.map +1 -0
- package/lib/core/SessionManager.d.ts +17 -0
- package/lib/core/SessionManager.d.ts.map +1 -0
- package/lib/core/SessionManager.js +57 -0
- package/lib/core/SessionManager.js.map +1 -0
- package/lib/core/Signer.d.ts +3 -0
- package/lib/core/Signer.d.ts.map +1 -0
- package/lib/core/Signer.js +26 -0
- package/lib/core/Signer.js.map +1 -0
- package/lib/index.d.ts +22 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/playwright.d.ts +46 -0
- package/lib/playwright.d.ts.map +1 -0
- package/lib/playwright.js +330 -0
- package/lib/playwright.js.map +1 -0
- package/lib/scrapers/CommentScraper.d.ts +6 -0
- package/lib/scrapers/CommentScraper.d.ts.map +1 -0
- package/lib/scrapers/CommentScraper.js +107 -0
- package/lib/scrapers/CommentScraper.js.map +1 -0
- package/lib/scrapers/ExtraScraper.d.ts +15 -0
- package/lib/scrapers/ExtraScraper.d.ts.map +1 -0
- package/lib/scrapers/ExtraScraper.js +244 -0
- package/lib/scrapers/ExtraScraper.js.map +1 -0
- package/lib/scrapers/FormatExtractor.d.ts +14 -0
- package/lib/scrapers/FormatExtractor.d.ts.map +1 -0
- package/lib/scrapers/FormatExtractor.js +110 -0
- package/lib/scrapers/FormatExtractor.js.map +1 -0
- package/lib/scrapers/ParserEngine.d.ts +17 -0
- package/lib/scrapers/ParserEngine.d.ts.map +1 -0
- package/lib/scrapers/ParserEngine.js +201 -0
- package/lib/scrapers/ParserEngine.js.map +1 -0
- package/lib/scrapers/SearchScraper.d.ts +5 -0
- package/lib/scrapers/SearchScraper.d.ts.map +1 -0
- package/lib/scrapers/SearchScraper.js +149 -0
- package/lib/scrapers/SearchScraper.js.map +1 -0
- package/lib/scrapers/UrlExtractor.d.ts +9 -0
- package/lib/scrapers/UrlExtractor.d.ts.map +1 -0
- package/lib/scrapers/UrlExtractor.js +34 -0
- package/lib/scrapers/UrlExtractor.js.map +1 -0
- package/lib/scrapers/UserScraper.d.ts +3 -0
- package/lib/scrapers/UserScraper.d.ts.map +1 -0
- package/lib/scrapers/UserScraper.js +137 -0
- package/lib/scrapers/UserScraper.js.map +1 -0
- package/lib/scrapers/VideoScraper.d.ts +3 -0
- package/lib/scrapers/VideoScraper.d.ts.map +1 -0
- package/lib/scrapers/VideoScraper.js +65 -0
- package/lib/scrapers/VideoScraper.js.map +1 -0
- package/lib/types.d.ts +483 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/CookieJar.d.ts +8 -0
- package/lib/utils/CookieJar.d.ts.map +1 -0
- package/lib/utils/CookieJar.js +51 -0
- package/lib/utils/CookieJar.js.map +1 -0
- package/lib/utils/HttpClient.d.ts +12 -0
- package/lib/utils/HttpClient.d.ts.map +1 -0
- package/lib/utils/HttpClient.js +39 -0
- package/lib/utils/HttpClient.js.map +1 -0
- package/lib/utils/constants.d.ts +41 -0
- package/lib/utils/constants.d.ts.map +1 -0
- package/lib/utils/constants.js +48 -0
- package/lib/utils/constants.js.map +1 -0
- package/lib/utils/errors.d.ts +31 -0
- package/lib/utils/errors.d.ts.map +1 -0
- package/lib/utils/errors.js +63 -0
- package/lib/utils/errors.js.map +1 -0
- package/lib/utils/helpers.d.ts +9 -0
- package/lib/utils/helpers.d.ts.map +1 -0
- package/lib/utils/helpers.js +41 -0
- package/lib/utils/helpers.js.map +1 -0
- package/lib/utils/xbogus.cjs +565 -0
- package/package.json +88 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Corex Anthony
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
<img src="https://raw.githubusercontent.com/Traceryn/tiktok-sdk/master/media/Traceryn.png" alt="Traceryn logo" width="320" />
|
|
2
|
+
|
|
3
|
+
# ***Traceryn/Tiktok-sdk***
|
|
4
|
+
A lightweight TikTok SDK for Node.js that makes it easier to fetch videos, users, comments, playlists, hashtags, and other TikTok data in a clean, structured way.
|
|
5
|
+
|
|
6
|
+
## Disclaimer
|
|
7
|
+
|
|
8
|
+
> [!CAUTION]
|
|
9
|
+
> This project is not affiliated with, endorsed by, or officially connected to TikTok or ByteDance.
|
|
10
|
+
> TikTok and related names, marks, logos, and images are trademarks of their respective owners.
|
|
11
|
+
>
|
|
12
|
+
> This SDK is provided for legitimate development use only. Use it at your own discretion and in accordance with TikTok's terms and applicable laws.
|
|
13
|
+
|
|
14
|
+
## How it works
|
|
15
|
+
|
|
16
|
+
- This SDK talks to TikTok through web endpoints and structured responses.
|
|
17
|
+
- Playwright is optional and only helps when a browser-backed session makes sense.
|
|
18
|
+
- That keeps the setup lighter for normal use and avoids needing a full browser just to start.
|
|
19
|
+
- It supports videos, users, comments, hashtags, playlists, sounds, and search data.
|
|
20
|
+
|
|
21
|
+
> [!IMPORTANT]
|
|
22
|
+
> This project is an unofficial TikTok SDK and depends on public endpoints and scraping behavior that may change at any time. Some features may require proxies, Playwright, or additional setup depending on your environment. Use responsibly and make sure your usage follows TikTok's terms and applicable laws.
|
|
23
|
+
|
|
24
|
+
> [!IMPORTANT]
|
|
25
|
+
> Some endpoints (`searchUsers`, `getSound`, `getSoundVideos`) are blocked by Akamai WAF from datacenter IPs. Pass `--session` to use a Playwright browser session that bypasses WAF.
|
|
26
|
+
>
|
|
27
|
+
> ```sh
|
|
28
|
+
> npm install playwright
|
|
29
|
+
> node docs/examples/getComments.cjs --session
|
|
30
|
+
> ```
|
|
31
|
+
|
|
32
|
+
> [!IMPORTANT]
|
|
33
|
+
> For deployment, use a VPS or another long-running server. This project runs into IP restrictions and blocks on most serverless hosts, so only a few platforms will work reliably. Vercel is a bad fit here, and Render only makes sense if you're using a service that stays up as a real web process.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
### Stable release
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npm install @traceryn/tiktok-sdk
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
yarn add @traceryn/tiktok-sdk
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### From GitHub
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm install git+https://github.com/traceryn/tiktok-sdk.git
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
yarn add git+https://github.com/traceryn/tiktok-sdk.git
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Optional: Playwright
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
npm install playwright
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
yarn add playwright
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Then import your code using:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { TikTokClient } from '@traceryn/tiktok-sdk';
|
|
71
|
+
|
|
72
|
+
const client = new TikTokClient();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
or
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const { TikTokClient } = require('@traceryn/tiktok-sdk');
|
|
79
|
+
|
|
80
|
+
const client = new TikTokClient();
|
|
81
|
+
```
|
|
82
|
+
> [!NOTE]
|
|
83
|
+
> Check the [examples](docs/examples) directory for runnable example scripts with the session pattern.
|
|
84
|
+
|
|
85
|
+
### Main methods
|
|
86
|
+
|
|
87
|
+
- `getVideo(url)` // get video data from a TikTok link
|
|
88
|
+
- `getUser(usernameOrUrl)` // get user profile data
|
|
89
|
+
- `getComments(videoUrl)` // get comments from a video or post
|
|
90
|
+
- `searchUsers(query)` // search for users
|
|
91
|
+
- `getHashtag(name)` // get hashtag stats
|
|
92
|
+
- `getSound(musicId)` // get sound info
|
|
93
|
+
- `getSoundVideos(musicId)` // get videos using a sound
|
|
94
|
+
- `getTrendingVideos()` // get trending videos
|
|
95
|
+
- `getUserLikedVideos(username)` // get videos a user liked
|
|
96
|
+
- `getUserPlaylists(username)` // get playlists for a user
|
|
97
|
+
- `getPlaylist(mixId)` // get one playlist
|
|
98
|
+
- `getPlaylistVideos(mixId)` // get videos inside a playlist
|
|
99
|
+
- `addProxies(proxies)` // add your own proxies
|
|
100
|
+
- `getProxyStats()` // check proxy usage
|
|
101
|
+
- `invalidateCache(url)` // clear one cached video
|
|
102
|
+
- `clearCache()` // clear all cached video data
|
|
103
|
+
|
|
104
|
+
## Examples
|
|
105
|
+
|
|
106
|
+
### Basic usage
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { TikTokClient } from '@traceryn/tiktok-sdk';
|
|
110
|
+
|
|
111
|
+
const client = new TikTokClient();
|
|
112
|
+
|
|
113
|
+
const video = await client.getVideo('https://www.tiktok.com/@user/video/1234567890');
|
|
114
|
+
console.log(video.title);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Gets one video and prints its title.
|
|
118
|
+
|
|
119
|
+
### Other methods
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const user = await client.getUser('tiktok');
|
|
123
|
+
console.log(user.nickname);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Gets a user profile from a username or profile link.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const comments = await client.getComments('https://www.tiktok.com/@user/video/1234567890');
|
|
130
|
+
console.log(comments.comments.length);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Gets the comments for a video or post.
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
const hashtag = await client.getHashtag('fyp');
|
|
137
|
+
console.log(hashtag.stats.videoCount);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Gets hashtag info and the number of videos tied to it.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const search = await client.searchUsers('tiktok');
|
|
144
|
+
console.log(search.users.length);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Searches for TikTok users by keyword.
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const trending = await client.getTrendingVideos();
|
|
151
|
+
console.log(trending.videos.length);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Gets the current trending videos.
|
|
155
|
+
|
|
156
|
+
### Using Playwright session
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
const { TikTokClient, PlaywrightSession } = require('@traceryn/tiktok-sdk');
|
|
160
|
+
|
|
161
|
+
async function main() {
|
|
162
|
+
const useSession = process.argv.includes('--session');
|
|
163
|
+
let session;
|
|
164
|
+
|
|
165
|
+
if (useSession) {
|
|
166
|
+
session = new PlaywrightSession({ headless: true });
|
|
167
|
+
await session.init();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const client = new TikTokClient({ session });
|
|
171
|
+
const trending = await client.getTrendingVideos();
|
|
172
|
+
|
|
173
|
+
console.log(trending.videos.length);
|
|
174
|
+
|
|
175
|
+
if (session) await session.close();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
main().catch((err) => {
|
|
179
|
+
console.error('Error:', err.message);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Settings
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { TikTokClient } from '@traceryn/tiktok-sdk';
|
|
188
|
+
|
|
189
|
+
const client = new TikTokClient({
|
|
190
|
+
timeout: 15000, // keep requests from hanging too long
|
|
191
|
+
maxRetries: 2, // retry a couple times if TikTok flakes out
|
|
192
|
+
rateLimit: 3, // slow it down a bit
|
|
193
|
+
concurrency: 1, // keep it simple and steady
|
|
194
|
+
cacheTTL: 60_000, // cache results for a minute
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
| Option | What you can change it to |
|
|
199
|
+
| --- | --- |
|
|
200
|
+
| `timeout` | Any number in milliseconds, like `5000`, `15000`, or `30000` |
|
|
201
|
+
| `maxRetries` | Any whole number, like `0`, `2`, or `5` |
|
|
202
|
+
| `rateLimit` | Any whole number, like `1`, `3`, or `10` |
|
|
203
|
+
| `concurrency` | Any whole number, like `1`, `2`, or `4` |
|
|
204
|
+
| `cacheTTL` | Any number in milliseconds, like `30000`, `60000`, or `300000` |
|
|
205
|
+
| `proxy` | A single proxy URL or array, like `"http://user:pass@host:port"` |
|
|
206
|
+
| `proxyRotation` | `"round-robin"`, `"random"`, or `"lowest-failures"` |
|
|
207
|
+
|
|
208
|
+
You can also pass `session` if you want the Playwright path, or `proxy` / `proxyRotation` if you want to manage proxies a bit more directly.
|
|
209
|
+
|
|
210
|
+
### IP throttling & proxies
|
|
211
|
+
|
|
212
|
+
TikTok rate-limits endpoints based on IP. If a request returns an empty response or gets throttled after heavy use, the fix is to switch IP via a proxy.
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
node docs/examples/searchUsers.cjs --session --proxy=http://user:pass@host:port
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
You can also add proxies at runtime:
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
client.addProxies(['http://user:pass@host:port', 'http://proxy2:port']);
|
|
222
|
+
console.log(client.getProxyStats());
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Free public proxies are often blocked by TikTok — residential or paid proxies are the most reliable for high-volume use. The SDK auto-rotates to the next healthy proxy when one fails.
|
|
226
|
+
|
|
227
|
+
> [!NOTE]
|
|
228
|
+
> You can also check [HERE](docs/responses) to see example response data for the main methods.
|
|
229
|
+
|
|
230
|
+
## Running tests
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
npm test
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
That runs the Vitest suite for this repo. Most of the tests are local, but some checks still depend on TikTok behavior and can shift when the site changes.
|
|
237
|
+
|
|
238
|
+
If you want a slightly wider check while you're working on the SDK, you can also run:
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
npm run typecheck
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
npm run lint
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
If you're only testing one area, keep the focus tight and run the smallest check that covers your change.
|
|
249
|
+
|
|
250
|
+
## Sponsor
|
|
251
|
+
If you'd like to financially support this project, sponsorship by the current maintainer is coming soon.
|
|
252
|
+
|
|
253
|
+
## Contributing
|
|
254
|
+
|
|
255
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute, and [SECURITY.md](SECURITY.md) for how to report security issues.
|
|
256
|
+
|
|
257
|
+
## LICENSE
|
|
258
|
+
Copyright (c) 2026 Corex Anthony
|
|
259
|
+
|
|
260
|
+
Licensed under the MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
261
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
262
|
+
in the Software without restriction, including without limitation the rights
|
|
263
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
264
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
265
|
+
furnished to do so, subject to the following conditions:
|
|
266
|
+
|
|
267
|
+
The above copyright notice and this permission notice shall be included in all
|
|
268
|
+
copies or substantial portions of the Software.
|
|
269
|
+
|
|
270
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
271
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
272
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
273
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
274
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
275
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
276
|
+
SOFTWARE.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Proxymanager } from './core/Proxymanager.js';
|
|
2
|
+
export interface ProxiflyConfig {
|
|
3
|
+
protocol?: 'http' | 'socks4' | 'socks5';
|
|
4
|
+
country?: string;
|
|
5
|
+
https?: boolean;
|
|
6
|
+
quantity?: number;
|
|
7
|
+
refreshInterval?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class ProxiflyProvider {
|
|
10
|
+
private proxyManager;
|
|
11
|
+
private defaults;
|
|
12
|
+
private refreshTimer;
|
|
13
|
+
private _ready;
|
|
14
|
+
private _resolveReady;
|
|
15
|
+
private _rejectReady;
|
|
16
|
+
private _fulfilled;
|
|
17
|
+
constructor(proxyManager: Proxymanager, config?: ProxiflyConfig, manualProxies?: string[]);
|
|
18
|
+
get ready(): Promise<void>;
|
|
19
|
+
get isReady(): boolean;
|
|
20
|
+
fetchFromCDN(): Promise<string[]>;
|
|
21
|
+
startAutoRefresh(): void;
|
|
22
|
+
stopAutoRefresh(): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ProxiflyProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProxiflyProvider.d.ts","sourceRoot":"","sources":["../src/ProxiflyProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,UAAU,CAAS;gBAGzB,YAAY,EAAE,YAAY,EAC1B,MAAM,CAAC,EAAE,cAAc,EACvB,aAAa,CAAC,EAAE,MAAM,EAAE;IA2C1B,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAsCvC,gBAAgB,IAAI,IAAI;IAYxB,eAAe,IAAI,IAAI;CAMxB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { ofetch } from 'ofetch';
|
|
2
|
+
import { Proxymanager } from './core/Proxymanager.js';
|
|
3
|
+
const CDN_BASE = 'https://cdn.jsdelivr.net/gh/proxifly/free-proxy-list@main/proxies';
|
|
4
|
+
export class ProxiflyProvider {
|
|
5
|
+
proxyManager;
|
|
6
|
+
defaults;
|
|
7
|
+
refreshTimer = null;
|
|
8
|
+
_ready;
|
|
9
|
+
_resolveReady;
|
|
10
|
+
_rejectReady;
|
|
11
|
+
_fulfilled = false;
|
|
12
|
+
constructor(proxyManager, config, manualProxies) {
|
|
13
|
+
this.proxyManager = proxyManager;
|
|
14
|
+
if (manualProxies?.length) {
|
|
15
|
+
proxyManager.addProxies(manualProxies);
|
|
16
|
+
}
|
|
17
|
+
this.defaults = {
|
|
18
|
+
protocol: 'http',
|
|
19
|
+
country: 'US',
|
|
20
|
+
https: true,
|
|
21
|
+
quantity: 10,
|
|
22
|
+
refreshInterval: 300_000,
|
|
23
|
+
...config,
|
|
24
|
+
};
|
|
25
|
+
this._ready = new Promise((resolve, reject) => {
|
|
26
|
+
this._resolveReady = resolve;
|
|
27
|
+
this._rejectReady = reject;
|
|
28
|
+
});
|
|
29
|
+
if (manualProxies?.length) {
|
|
30
|
+
this._fulfilled = true;
|
|
31
|
+
this._resolveReady();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.fetchFromCDN()
|
|
35
|
+
.then((urls) => {
|
|
36
|
+
if (urls.length > 0) {
|
|
37
|
+
this.proxyManager.addProxies(urls);
|
|
38
|
+
this._fulfilled = true;
|
|
39
|
+
this._resolveReady();
|
|
40
|
+
this.startAutoRefresh();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this._rejectReady(new Error('ProxiflyProvider: no proxies returned from CDN'));
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.catch((err) => {
|
|
47
|
+
this._rejectReady(err);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
get ready() {
|
|
52
|
+
return this._ready;
|
|
53
|
+
}
|
|
54
|
+
get isReady() {
|
|
55
|
+
return this._fulfilled;
|
|
56
|
+
}
|
|
57
|
+
async fetchFromCDN() {
|
|
58
|
+
const country = this.defaults.country?.toUpperCase() ?? '';
|
|
59
|
+
const protocol = this.defaults.protocol ?? 'http';
|
|
60
|
+
const sources = [
|
|
61
|
+
country ? `${CDN_BASE}/countries/${country}/data.txt` : null,
|
|
62
|
+
`${CDN_BASE}/protocols/${protocol}/data.txt`,
|
|
63
|
+
`${CDN_BASE}/all/data.txt`,
|
|
64
|
+
].filter(Boolean);
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
for (const url of sources) {
|
|
67
|
+
try {
|
|
68
|
+
const text = await ofetch(url, {
|
|
69
|
+
parseResponse: (t) => t,
|
|
70
|
+
timeout: 10000,
|
|
71
|
+
});
|
|
72
|
+
for (const line of text.split('\n')) {
|
|
73
|
+
const trimmed = line.trim();
|
|
74
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
75
|
+
continue;
|
|
76
|
+
if (trimmed.includes('://')) {
|
|
77
|
+
if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
|
|
78
|
+
seen.add(trimmed);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
seen.add(`http://${trimmed}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (seen.size >= (this.defaults.quantity ?? 10))
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
}
|
|
90
|
+
return Array.from(seen).slice(0, this.defaults.quantity ?? 10);
|
|
91
|
+
}
|
|
92
|
+
startAutoRefresh() {
|
|
93
|
+
if (this.refreshTimer)
|
|
94
|
+
return;
|
|
95
|
+
const interval = this.defaults.refreshInterval ?? 300_000;
|
|
96
|
+
this.refreshTimer = setInterval(() => {
|
|
97
|
+
this.fetchFromCDN()
|
|
98
|
+
.then((urls) => {
|
|
99
|
+
if (urls.length > 0)
|
|
100
|
+
this.proxyManager.addProxies(urls);
|
|
101
|
+
})
|
|
102
|
+
.catch(() => { });
|
|
103
|
+
}, interval);
|
|
104
|
+
}
|
|
105
|
+
stopAutoRefresh() {
|
|
106
|
+
if (this.refreshTimer) {
|
|
107
|
+
clearInterval(this.refreshTimer);
|
|
108
|
+
this.refreshTimer = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=ProxiflyProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProxiflyProvider.js","sourceRoot":"","sources":["../src/ProxiflyProvider.ts"],"names":[],"mappings":"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"}
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TikTokVideo, TikTokUser, TikTokUserSearchResults, TikTokCommentList, ClientOptions, HashtagInfo, SoundInfo, SoundItemList, TrendingVideos, LikedVideos, PlaylistInfo, PlaylistItemList } from './types.js';
|
|
2
|
+
export declare class TikTokClient {
|
|
3
|
+
private options;
|
|
4
|
+
private proxyManager;
|
|
5
|
+
private proxiflyProvider;
|
|
6
|
+
private rateLimiter;
|
|
7
|
+
private retryHandler;
|
|
8
|
+
private circuitBreaker;
|
|
9
|
+
private cache;
|
|
10
|
+
private sessionManager;
|
|
11
|
+
private queue;
|
|
12
|
+
constructor(options?: ClientOptions);
|
|
13
|
+
private awaitProxy;
|
|
14
|
+
addProxies(proxies: string[]): void;
|
|
15
|
+
getVideo(url: string, useCache?: boolean): Promise<TikTokVideo>;
|
|
16
|
+
private executeGetVideo;
|
|
17
|
+
getUser(usernameOrUrl: string, useCache?: boolean): Promise<TikTokUser>;
|
|
18
|
+
private executeGetUser;
|
|
19
|
+
downloadVideo(videoUrl: string): Promise<ArrayBuffer>;
|
|
20
|
+
getProxyStats(): {
|
|
21
|
+
total: number;
|
|
22
|
+
enabled: number;
|
|
23
|
+
avgScore: number;
|
|
24
|
+
};
|
|
25
|
+
searchUsers(query: string, cursor?: number, count?: number): Promise<TikTokUserSearchResults>;
|
|
26
|
+
getComments(videoUrl: string, cursor?: number, count?: number): Promise<TikTokCommentList>;
|
|
27
|
+
getHashtag(name: string): Promise<HashtagInfo>;
|
|
28
|
+
getSound(musicId: string): Promise<SoundInfo>;
|
|
29
|
+
getSoundVideos(musicId: string, cursor?: number, count?: number): Promise<SoundItemList>;
|
|
30
|
+
getTrendingVideos(count?: number): Promise<TrendingVideos>;
|
|
31
|
+
getUserLikedVideos(username: string, cursor?: number, count?: number): Promise<LikedVideos>;
|
|
32
|
+
getUserPlaylists(username: string, cursor?: number, count?: number): Promise<{
|
|
33
|
+
playlists: PlaylistInfo[];
|
|
34
|
+
cursor: number;
|
|
35
|
+
hasMore: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
getPlaylist(mixId: string): Promise<PlaylistInfo>;
|
|
38
|
+
getPlaylistVideos(mixId: string, cursor?: number, count?: number): Promise<PlaylistItemList>;
|
|
39
|
+
invalidateCache(url: string): void;
|
|
40
|
+
clearCache(): void;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,aAAa,EAAsB,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAqC7O,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAe;gBAEhB,OAAO,GAAE,aAAkB;YAiCzB,UAAU;IAUxB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAI7B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,UAAO,GAAG,OAAO,CAAC,WAAW,CAAC;YAapD,eAAe;IA2LvB,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,UAAO,GAAG,OAAO,CAAC,UAAU,CAAC;YAc5D,cAAc;IA0CtB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAyB3D,aAAa;;;;;IAIP,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAMzF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQtF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAM9C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAM7C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IAMpF,iBAAiB,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,cAAc,CAAC;IAMtD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,WAAW,CAAC;IAOvF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAOzI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAMjD,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAM9F,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIlC,UAAU,IAAI,IAAI;CAGnB"}
|