@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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +276 -0
  3. package/engineRequirements.js +7 -0
  4. package/lib/ProxiflyProvider.d.ts +24 -0
  5. package/lib/ProxiflyProvider.d.ts.map +1 -0
  6. package/lib/ProxiflyProvider.js +112 -0
  7. package/lib/ProxiflyProvider.js.map +1 -0
  8. package/lib/client.d.ts +42 -0
  9. package/lib/client.d.ts.map +1 -0
  10. package/lib/client.js +377 -0
  11. package/lib/client.js.map +1 -0
  12. package/lib/core/CacheManager.d.ts +13 -0
  13. package/lib/core/CacheManager.d.ts.map +1 -0
  14. package/lib/core/CacheManager.js +49 -0
  15. package/lib/core/CacheManager.js.map +1 -0
  16. package/lib/core/CircuitBreaker.d.ts +21 -0
  17. package/lib/core/CircuitBreaker.d.ts.map +1 -0
  18. package/lib/core/CircuitBreaker.js +64 -0
  19. package/lib/core/CircuitBreaker.js.map +1 -0
  20. package/lib/core/Proxymanager.d.ts +32 -0
  21. package/lib/core/Proxymanager.d.ts.map +1 -0
  22. package/lib/core/Proxymanager.js +129 -0
  23. package/lib/core/Proxymanager.js.map +1 -0
  24. package/lib/core/RateLimiter.d.ts +17 -0
  25. package/lib/core/RateLimiter.d.ts.map +1 -0
  26. package/lib/core/RateLimiter.js +53 -0
  27. package/lib/core/RateLimiter.js.map +1 -0
  28. package/lib/core/RequestQueue.d.ts +17 -0
  29. package/lib/core/RequestQueue.d.ts.map +1 -0
  30. package/lib/core/RequestQueue.js +51 -0
  31. package/lib/core/RequestQueue.js.map +1 -0
  32. package/lib/core/RetryHandler.d.ts +13 -0
  33. package/lib/core/RetryHandler.d.ts.map +1 -0
  34. package/lib/core/RetryHandler.js +37 -0
  35. package/lib/core/RetryHandler.js.map +1 -0
  36. package/lib/core/SessionManager.d.ts +17 -0
  37. package/lib/core/SessionManager.d.ts.map +1 -0
  38. package/lib/core/SessionManager.js +57 -0
  39. package/lib/core/SessionManager.js.map +1 -0
  40. package/lib/core/Signer.d.ts +3 -0
  41. package/lib/core/Signer.d.ts.map +1 -0
  42. package/lib/core/Signer.js +26 -0
  43. package/lib/core/Signer.js.map +1 -0
  44. package/lib/index.d.ts +22 -0
  45. package/lib/index.d.ts.map +1 -0
  46. package/lib/index.js +21 -0
  47. package/lib/index.js.map +1 -0
  48. package/lib/playwright.d.ts +46 -0
  49. package/lib/playwright.d.ts.map +1 -0
  50. package/lib/playwright.js +330 -0
  51. package/lib/playwright.js.map +1 -0
  52. package/lib/scrapers/CommentScraper.d.ts +6 -0
  53. package/lib/scrapers/CommentScraper.d.ts.map +1 -0
  54. package/lib/scrapers/CommentScraper.js +107 -0
  55. package/lib/scrapers/CommentScraper.js.map +1 -0
  56. package/lib/scrapers/ExtraScraper.d.ts +15 -0
  57. package/lib/scrapers/ExtraScraper.d.ts.map +1 -0
  58. package/lib/scrapers/ExtraScraper.js +244 -0
  59. package/lib/scrapers/ExtraScraper.js.map +1 -0
  60. package/lib/scrapers/FormatExtractor.d.ts +14 -0
  61. package/lib/scrapers/FormatExtractor.d.ts.map +1 -0
  62. package/lib/scrapers/FormatExtractor.js +110 -0
  63. package/lib/scrapers/FormatExtractor.js.map +1 -0
  64. package/lib/scrapers/ParserEngine.d.ts +17 -0
  65. package/lib/scrapers/ParserEngine.d.ts.map +1 -0
  66. package/lib/scrapers/ParserEngine.js +201 -0
  67. package/lib/scrapers/ParserEngine.js.map +1 -0
  68. package/lib/scrapers/SearchScraper.d.ts +5 -0
  69. package/lib/scrapers/SearchScraper.d.ts.map +1 -0
  70. package/lib/scrapers/SearchScraper.js +149 -0
  71. package/lib/scrapers/SearchScraper.js.map +1 -0
  72. package/lib/scrapers/UrlExtractor.d.ts +9 -0
  73. package/lib/scrapers/UrlExtractor.d.ts.map +1 -0
  74. package/lib/scrapers/UrlExtractor.js +34 -0
  75. package/lib/scrapers/UrlExtractor.js.map +1 -0
  76. package/lib/scrapers/UserScraper.d.ts +3 -0
  77. package/lib/scrapers/UserScraper.d.ts.map +1 -0
  78. package/lib/scrapers/UserScraper.js +137 -0
  79. package/lib/scrapers/UserScraper.js.map +1 -0
  80. package/lib/scrapers/VideoScraper.d.ts +3 -0
  81. package/lib/scrapers/VideoScraper.d.ts.map +1 -0
  82. package/lib/scrapers/VideoScraper.js +65 -0
  83. package/lib/scrapers/VideoScraper.js.map +1 -0
  84. package/lib/types.d.ts +483 -0
  85. package/lib/types.d.ts.map +1 -0
  86. package/lib/types.js +2 -0
  87. package/lib/types.js.map +1 -0
  88. package/lib/utils/CookieJar.d.ts +8 -0
  89. package/lib/utils/CookieJar.d.ts.map +1 -0
  90. package/lib/utils/CookieJar.js +51 -0
  91. package/lib/utils/CookieJar.js.map +1 -0
  92. package/lib/utils/HttpClient.d.ts +12 -0
  93. package/lib/utils/HttpClient.d.ts.map +1 -0
  94. package/lib/utils/HttpClient.js +39 -0
  95. package/lib/utils/HttpClient.js.map +1 -0
  96. package/lib/utils/constants.d.ts +41 -0
  97. package/lib/utils/constants.d.ts.map +1 -0
  98. package/lib/utils/constants.js +48 -0
  99. package/lib/utils/constants.js.map +1 -0
  100. package/lib/utils/errors.d.ts +31 -0
  101. package/lib/utils/errors.d.ts.map +1 -0
  102. package/lib/utils/errors.js +63 -0
  103. package/lib/utils/errors.js.map +1 -0
  104. package/lib/utils/helpers.d.ts +9 -0
  105. package/lib/utils/helpers.d.ts.map +1 -0
  106. package/lib/utils/helpers.js +41 -0
  107. package/lib/utils/helpers.js.map +1 -0
  108. package/lib/utils/xbogus.cjs +565 -0
  109. 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,7 @@
1
+ const nodeVersion = process.versions.node;
2
+ const major = Number(nodeVersion.split('.')[0]);
3
+ if (major < 18) {
4
+ console.error(`❌ Node.js >= 18 required (found ${nodeVersion})`);
5
+ process.exit(1);
6
+ }
7
+ console.log(`✓ Node.js ${nodeVersion}`);
@@ -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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"}
@@ -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"}