douyin-downloader 0.1.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 (161) hide show
  1. package/README.md +114 -0
  2. package/dist/bin/dydl.d.ts +2 -0
  3. package/dist/bin/dydl.js +17 -0
  4. package/dist/bin/dydl.js.map +1 -0
  5. package/dist/src/cli/commands/check.d.ts +10 -0
  6. package/dist/src/cli/commands/check.js +102 -0
  7. package/dist/src/cli/commands/check.js.map +1 -0
  8. package/dist/src/cli/commands/info.d.ts +10 -0
  9. package/dist/src/cli/commands/info.js +106 -0
  10. package/dist/src/cli/commands/info.js.map +1 -0
  11. package/dist/src/cli/commands/list.d.ts +10 -0
  12. package/dist/src/cli/commands/list.js +85 -0
  13. package/dist/src/cli/commands/list.js.map +1 -0
  14. package/dist/src/cli/commands/login.d.ts +10 -0
  15. package/dist/src/cli/commands/login.js +158 -0
  16. package/dist/src/cli/commands/login.js.map +1 -0
  17. package/dist/src/cli/commands/open.d.ts +10 -0
  18. package/dist/src/cli/commands/open.js +141 -0
  19. package/dist/src/cli/commands/open.js.map +1 -0
  20. package/dist/src/cli/commands/video.d.ts +10 -0
  21. package/dist/src/cli/commands/video.js +209 -0
  22. package/dist/src/cli/commands/video.js.map +1 -0
  23. package/dist/src/cli/index.d.ts +15 -0
  24. package/dist/src/cli/index.js +134 -0
  25. package/dist/src/cli/index.js.map +1 -0
  26. package/dist/src/cli/progress-display.d.ts +80 -0
  27. package/dist/src/cli/progress-display.js +225 -0
  28. package/dist/src/cli/progress-display.js.map +1 -0
  29. package/dist/src/cli/utils.d.ts +31 -0
  30. package/dist/src/cli/utils.js +171 -0
  31. package/dist/src/cli/utils.js.map +1 -0
  32. package/dist/src/douyin/auth/cookie-path.d.ts +22 -0
  33. package/dist/src/douyin/auth/cookie-path.js +72 -0
  34. package/dist/src/douyin/auth/cookie-path.js.map +1 -0
  35. package/dist/src/douyin/auth/cookie-storage.d.ts +19 -0
  36. package/dist/src/douyin/auth/cookie-storage.js +65 -0
  37. package/dist/src/douyin/auth/cookie-storage.js.map +1 -0
  38. package/dist/src/douyin/auth/errors.d.ts +28 -0
  39. package/dist/src/douyin/auth/errors.js +49 -0
  40. package/dist/src/douyin/auth/errors.js.map +1 -0
  41. package/dist/src/douyin/auth/getDefaultCookiePath.d.ts +24 -0
  42. package/dist/src/douyin/auth/getDefaultCookiePath.js +90 -0
  43. package/dist/src/douyin/auth/getDefaultCookiePath.js.map +1 -0
  44. package/dist/src/douyin/auth/index.d.ts +16 -0
  45. package/dist/src/douyin/auth/index.js +68 -0
  46. package/dist/src/douyin/auth/index.js.map +1 -0
  47. package/dist/src/douyin/auth/isValidCookie.d.ts +18 -0
  48. package/dist/src/douyin/auth/isValidCookie.js +60 -0
  49. package/dist/src/douyin/auth/isValidCookie.js.map +1 -0
  50. package/dist/src/douyin/auth/loadAndValidateCookie.d.ts +17 -0
  51. package/dist/src/douyin/auth/loadAndValidateCookie.js +45 -0
  52. package/dist/src/douyin/auth/loadAndValidateCookie.js.map +1 -0
  53. package/dist/src/douyin/auth/loadCookie.d.ts +17 -0
  54. package/dist/src/douyin/auth/loadCookie.js +79 -0
  55. package/dist/src/douyin/auth/loadCookie.js.map +1 -0
  56. package/dist/src/douyin/auth/login.d.ts +33 -0
  57. package/dist/src/douyin/auth/login.js +157 -0
  58. package/dist/src/douyin/auth/login.js.map +1 -0
  59. package/dist/src/douyin/auth/saveCookie.d.ts +17 -0
  60. package/dist/src/douyin/auth/saveCookie.js +89 -0
  61. package/dist/src/douyin/auth/saveCookie.js.map +1 -0
  62. package/dist/src/douyin/auth/validate.d.ts +11 -0
  63. package/dist/src/douyin/auth/validate.js +104 -0
  64. package/dist/src/douyin/auth/validate.js.map +1 -0
  65. package/dist/src/douyin/browser/manager.d.ts +54 -0
  66. package/dist/src/douyin/browser/manager.js +344 -0
  67. package/dist/src/douyin/browser/manager.js.map +1 -0
  68. package/dist/src/douyin/download/download-manager.d.ts +25 -0
  69. package/dist/src/douyin/download/download-manager.js +107 -0
  70. package/dist/src/douyin/download/download-manager.js.map +1 -0
  71. package/dist/src/douyin/download/error-handler.d.ts +49 -0
  72. package/dist/src/douyin/download/error-handler.js +160 -0
  73. package/dist/src/douyin/download/error-handler.js.map +1 -0
  74. package/dist/src/douyin/download/index.d.ts +39 -0
  75. package/dist/src/douyin/download/index.js +156 -0
  76. package/dist/src/douyin/download/index.js.map +1 -0
  77. package/dist/src/douyin/download/path-formatter.d.ts +42 -0
  78. package/dist/src/douyin/download/path-formatter.js +107 -0
  79. package/dist/src/douyin/download/path-formatter.js.map +1 -0
  80. package/dist/src/douyin/download/video-downloader.d.ts +35 -0
  81. package/dist/src/douyin/download/video-downloader.js +223 -0
  82. package/dist/src/douyin/download/video-downloader.js.map +1 -0
  83. package/dist/src/douyin/index.d.ts +19 -0
  84. package/dist/src/douyin/index.js +52 -0
  85. package/dist/src/douyin/index.js.map +1 -0
  86. package/dist/src/douyin/info/batch-processor.d.ts +15 -0
  87. package/dist/src/douyin/info/batch-processor.js +65 -0
  88. package/dist/src/douyin/info/batch-processor.js.map +1 -0
  89. package/dist/src/douyin/info/browser-manager.d.ts +56 -0
  90. package/dist/src/douyin/info/browser-manager.js +225 -0
  91. package/dist/src/douyin/info/browser-manager.js.map +1 -0
  92. package/dist/src/douyin/info/error-handler.d.ts +36 -0
  93. package/dist/src/douyin/info/error-handler.js +172 -0
  94. package/dist/src/douyin/info/error-handler.js.map +1 -0
  95. package/dist/src/douyin/info/fetch-video-detail.d.ts +14 -0
  96. package/dist/src/douyin/info/fetch-video-detail.js +247 -0
  97. package/dist/src/douyin/info/fetch-video-detail.js.map +1 -0
  98. package/dist/src/douyin/info/index.d.ts +29 -0
  99. package/dist/src/douyin/info/index.js +85 -0
  100. package/dist/src/douyin/info/index.js.map +1 -0
  101. package/dist/src/douyin/info/text-processor.d.ts +15 -0
  102. package/dist/src/douyin/info/text-processor.js +47 -0
  103. package/dist/src/douyin/info/text-processor.js.map +1 -0
  104. package/dist/src/douyin/info/user.d.ts +26 -0
  105. package/dist/src/douyin/info/user.js +237 -0
  106. package/dist/src/douyin/info/user.js.map +1 -0
  107. package/dist/src/douyin/parser/containsDouyinLink.d.ts +18 -0
  108. package/dist/src/douyin/parser/containsDouyinLink.js +27 -0
  109. package/dist/src/douyin/parser/containsDouyinLink.js.map +1 -0
  110. package/dist/src/douyin/parser/extract-links.d.ts +23 -0
  111. package/dist/src/douyin/parser/extract-links.js +79 -0
  112. package/dist/src/douyin/parser/extract-links.js.map +1 -0
  113. package/dist/src/douyin/parser/extractDouyinLinks.d.ts +18 -0
  114. package/dist/src/douyin/parser/extractDouyinLinks.js +58 -0
  115. package/dist/src/douyin/parser/extractDouyinLinks.js.map +1 -0
  116. package/dist/src/douyin/parser/index.d.ts +35 -0
  117. package/dist/src/douyin/parser/index.js +70 -0
  118. package/dist/src/douyin/parser/index.js.map +1 -0
  119. package/dist/src/douyin/parser/link-patterns.d.ts +34 -0
  120. package/dist/src/douyin/parser/link-patterns.js +121 -0
  121. package/dist/src/douyin/parser/link-patterns.js.map +1 -0
  122. package/dist/src/douyin/parser/parse-batch.d.ts +26 -0
  123. package/dist/src/douyin/parser/parse-batch.js +67 -0
  124. package/dist/src/douyin/parser/parse-batch.js.map +1 -0
  125. package/dist/src/douyin/parser/parseDouyinLinks.d.ts +30 -0
  126. package/dist/src/douyin/parser/parseDouyinLinks.js +164 -0
  127. package/dist/src/douyin/parser/parseDouyinLinks.js.map +1 -0
  128. package/dist/src/douyin/parser/resolve-links.d.ts +25 -0
  129. package/dist/src/douyin/parser/resolve-links.js +131 -0
  130. package/dist/src/douyin/parser/resolve-links.js.map +1 -0
  131. package/dist/src/index.d.ts +16 -0
  132. package/dist/src/index.js +72 -0
  133. package/dist/src/index.js.map +1 -0
  134. package/dist/src/types.d.ts +217 -0
  135. package/dist/src/types.js +6 -0
  136. package/dist/src/types.js.map +1 -0
  137. package/dist/src/utils/browser.d.ts +73 -0
  138. package/dist/src/utils/browser.js +96 -0
  139. package/dist/src/utils/browser.js.map +1 -0
  140. package/dist/src/utils/error.d.ts +160 -0
  141. package/dist/src/utils/error.js +334 -0
  142. package/dist/src/utils/error.js.map +1 -0
  143. package/dist/src/utils/fetch.d.ts +41 -0
  144. package/dist/src/utils/fetch.js +155 -0
  145. package/dist/src/utils/fetch.js.map +1 -0
  146. package/dist/src/utils/file.d.ts +46 -0
  147. package/dist/src/utils/file.js +189 -0
  148. package/dist/src/utils/file.js.map +1 -0
  149. package/dist/src/utils/index.d.ts +11 -0
  150. package/dist/src/utils/index.js +29 -0
  151. package/dist/src/utils/index.js.map +1 -0
  152. package/dist/src/utils/logger.d.ts +161 -0
  153. package/dist/src/utils/logger.js +286 -0
  154. package/dist/src/utils/logger.js.map +1 -0
  155. package/dist/src/utils/performance.d.ts +98 -0
  156. package/dist/src/utils/performance.js +292 -0
  157. package/dist/src/utils/performance.js.map +1 -0
  158. package/dist/src/utils/retry.d.ts +56 -0
  159. package/dist/src/utils/retry.js +127 -0
  160. package/dist/src/utils/retry.js.map +1 -0
  161. package/package.json +61 -0
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ // Copied from src/info/user.ts
3
+ // Original file path: src/info/user.ts
4
+ /**
5
+ * 用戶影片獲取模組
6
+ * 提供獲取抖音用戶發布影片列表的功能
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getOfficialVideoUrl = getOfficialVideoUrl;
10
+ exports.extractSecUserId = extractSecUserId;
11
+ exports.fetchUserVideos = fetchUserVideos;
12
+ const logger_1 = require("../../utils/logger");
13
+ const fetch_1 = require("../../utils/fetch"); // Import the general fetch utility
14
+ const error_handler_1 = require("./error-handler"); // Assuming this path is correct relative to the new location
15
+ /**
16
+ * 抖音 API 專用的 GET 請求函數
17
+ * @param url API URL
18
+ * @param params 查詢參數
19
+ * @param options 請求選項
20
+ * @returns Promise<any> API 響應
21
+ */
22
+ async function douyinApiGet(url, params = {}, options = {}) {
23
+ // 構建完整的 URL,包含查詢參數
24
+ const queryString = new URLSearchParams(params).toString();
25
+ const fullUrl = `${url}${url.includes('?') ? '&' : '?'}${queryString}`;
26
+ // 使用通用的 getJson 函數發送請求
27
+ return await (0, fetch_1.getJson)(fullUrl, options);
28
+ }
29
+ /**
30
+ * 從 URL 列表中獲取官方影片下載地址
31
+ * @param urlList URL 列表
32
+ * @returns 官方影片下載地址
33
+ */
34
+ function getOfficialVideoUrl(urlList) {
35
+ if (!urlList || urlList.length === 0)
36
+ return '';
37
+ // API返回的url_list通常包含多個URL,其中包含官方下載地址
38
+ // 檢查每個URL,返回官方格式的鏈接
39
+ for (const url of urlList) {
40
+ if (url.includes('douyin.com/aweme/v1/play')) {
41
+ return url;
42
+ }
43
+ }
44
+ // 如果沒有找到官方鏈接,則返回第一個鏈接作為後備
45
+ return urlList[0];
46
+ }
47
+ // 抖音用戶作品 API
48
+ const USER_POST_API = 'https://www.douyin.com/aweme/v1/web/aweme/post/';
49
+ // 抖音用戶喜歡作品 API
50
+ const USER_FAVORITE_API = 'https://www.douyin.com/aweme/v1/web/aweme/favorite/';
51
+ /**
52
+ * 從 URL 中提取用戶 ID (sec_uid)
53
+ * @param userUrl 用戶主頁 URL
54
+ * @returns 用戶 ID 或 null
55
+ */
56
+ function extractSecUserId(userUrl) {
57
+ try {
58
+ // 嘗試從 URL 參數中提取
59
+ const urlObj = new URL(userUrl);
60
+ // Correct parameter name: sec_user_id instead of sec_uid
61
+ const secUid = urlObj.searchParams.get('sec_user_id');
62
+ // Removed temporary debug log
63
+ if (secUid) {
64
+ return secUid;
65
+ }
66
+ // 嘗試從路徑中提取
67
+ const pathMatch = userUrl.match(/\/user\/([^?/]+)/);
68
+ if (pathMatch && pathMatch[1]) {
69
+ return pathMatch[1];
70
+ }
71
+ logger_1.infoLogger.warn(`無法從 URL 中提取用戶 ID: ${userUrl}`);
72
+ return null;
73
+ }
74
+ catch (error) {
75
+ // Ensure the caught error is treated as an Error object for the logger
76
+ const errorMsg = error instanceof Error ? error.message : String(error);
77
+ logger_1.infoLogger.error(`解析用戶 URL 失敗: ${userUrl}`, error instanceof Error ? error : new Error(errorMsg));
78
+ return null;
79
+ }
80
+ }
81
+ /**
82
+ * 獲取用戶影片分頁數據
83
+ * @param apiUrl API URL
84
+ * @param secUserId 用戶 ID
85
+ * @param cursor 分頁游標
86
+ * @param cookie Cookie 字串
87
+ * @returns Promise<{videos: UserVideoItem[], nextCursor: number, hasMore: boolean}>
88
+ */
89
+ async function fetchUserVideoPage(apiUrl, secUserId, cursor, cookie) {
90
+ // 構建請求參數
91
+ const params = {
92
+ sec_user_id: secUserId,
93
+ count: 20, // 每頁數量
94
+ max_cursor: cursor,
95
+ aid: '6383',
96
+ version_code: '170400',
97
+ device_platform: 'webapp',
98
+ cookie_enabled: 'true'
99
+ };
100
+ // 帶 Cookie 的請求頭
101
+ const headers = {
102
+ 'Cookie': cookie,
103
+ 'Referer': apiUrl.includes('favorite')
104
+ ? `https://www.douyin.com/user/${secUserId}?showTab=like`
105
+ : `https://www.douyin.com/user/${secUserId}`
106
+ };
107
+ // 使用重試機制發送請求
108
+ return await (0, error_handler_1.fetchWithRetry)(async () => {
109
+ try {
110
+ const response = await douyinApiGet(apiUrl, params, { headers });
111
+ // 檢查響應格式
112
+ if (!response.aweme_list || !Array.isArray(response.aweme_list)) {
113
+ throw new Error('獲取用戶影片列表失敗,響應數據格式異常');
114
+ }
115
+ // 檢查是否有錯誤信息
116
+ if (response.status_code && response.status_code !== 0) {
117
+ throw new Error(`獲取用戶影片失敗,狀態碼: ${response.status_code}, 信息: ${response.status_msg || '未知錯誤'}`);
118
+ }
119
+ // Use the defined AwemeItem type here
120
+ const videos = response.aweme_list.map((item) => {
121
+ const urlList = item.video?.play_addr?.url_list;
122
+ const videoPlayUrl = getOfficialVideoUrl(urlList); // Use helper to get a playable URL
123
+ return {
124
+ vid: item.aweme_id,
125
+ description: item.desc,
126
+ createTime: item.create_time,
127
+ videoPlayUrl: videoPlayUrl, // Assign the determined play URL
128
+ author: {
129
+ id: item.author?.sec_uid || item.author?.uid || '',
130
+ nickname: item.author?.nickname || '未知作者',
131
+ },
132
+ stats: {
133
+ playCount: item.statistics?.play_count,
134
+ likeCount: item.statistics?.digg_count, // digg_count 是點讚數
135
+ commentCount: item.statistics?.comment_count,
136
+ shareCount: item.statistics?.share_count,
137
+ },
138
+ };
139
+ });
140
+ return {
141
+ videos,
142
+ nextCursor: response.max_cursor,
143
+ hasMore: response.has_more === 1,
144
+ total: response.total
145
+ };
146
+ }
147
+ catch (error) {
148
+ // ... (error handling remains the same)
149
+ let statusCode;
150
+ let message;
151
+ if (typeof error === 'object' && error !== null) {
152
+ if ('response' in error && typeof error.response === 'object' && error.response !== null && 'status' in error.response) {
153
+ statusCode = error.response.status;
154
+ }
155
+ if ('message' in error && typeof error.message === 'string') {
156
+ message = error.message;
157
+ }
158
+ }
159
+ if (statusCode === 403 || (message && message.includes('403'))) {
160
+ logger_1.infoLogger.warn('無效的 Cookie 或權限不足,返回空列表');
161
+ return { videos: [], nextCursor: 0, hasMore: false };
162
+ }
163
+ throw error;
164
+ }
165
+ });
166
+ }
167
+ /**
168
+ * 獲取指定用戶的影片列表
169
+ * @param userUrl 用戶主頁 URL
170
+ * @param cookie 有效的抖音 Cookie
171
+ * @param limit 限制獲取的影片數量,0 表示獲取全部
172
+ * @param options 獲取選項
173
+ * @returns Promise<UserVideoItem[]> 用戶影片列表
174
+ */
175
+ async function fetchUserVideos(userUrl, cookie, limit = 0, options = {}) {
176
+ // 確認 Cookie 是否提供
177
+ if (!cookie || cookie.trim() === '') {
178
+ logger_1.infoLogger.error('未提供有效的 Cookie,無法獲取用戶影片');
179
+ throw new Error('需要有效的抖音 Cookie 才能獲取用戶影片');
180
+ }
181
+ // 提取用戶 ID
182
+ const secUserId = extractSecUserId(userUrl);
183
+ if (!secUserId) {
184
+ throw new Error(`無法從 URL 提取用戶 ID: ${userUrl}`);
185
+ }
186
+ logger_1.infoLogger.info(`開始獲取用戶 (${secUserId}) 的影片列表`);
187
+ // 確定是獲取用戶發布的影片還是喜歡的影片
188
+ const isLikedVideos = userUrl.includes('/user') && userUrl.includes('showTab=like');
189
+ const apiUrl = isLikedVideos ? USER_FAVORITE_API : USER_POST_API;
190
+ // 初始化結果和游標
191
+ const results = [];
192
+ let cursor = 0;
193
+ let hasMore = true;
194
+ let totalEstimated;
195
+ try {
196
+ // 分頁獲取數據
197
+ while (hasMore && (limit === 0 || results.length < limit)) {
198
+ logger_1.infoLogger.debug(`獲取用戶影片列表頁,當前游標: ${cursor}`);
199
+ // 獲取單頁數據
200
+ const { videos, nextCursor, hasMore: hasMoreData, total } = await fetchUserVideoPage(apiUrl, secUserId, cursor, cookie);
201
+ // 如果獲取到了總數,更新估計總數
202
+ if (total !== undefined) {
203
+ totalEstimated = total;
204
+ }
205
+ // 添加到結果中
206
+ results.push(...videos);
207
+ // 更新進度
208
+ if (options.onProgress) {
209
+ options.onProgress(results.length, totalEstimated);
210
+ }
211
+ // 更新游標和是否還有更多
212
+ cursor = nextCursor;
213
+ hasMore = hasMoreData;
214
+ // 如果已達到限制,截斷結果
215
+ if (limit > 0 && results.length >= limit) {
216
+ results.splice(limit);
217
+ break;
218
+ }
219
+ // 如果沒有更多數據,結束循環
220
+ if (!hasMore) {
221
+ break;
222
+ }
223
+ // 短暫延遲防止請求過於頻繁
224
+ await new Promise(resolve => setTimeout(resolve, 500));
225
+ logger_1.infoLogger.debug(`已獲取 ${results.length} 個影片${totalEstimated ? `,總計約 ${totalEstimated} 個` : ''}`);
226
+ }
227
+ logger_1.infoLogger.info(`成功獲取用戶 (${secUserId}) 的影片列表,共 ${results.length} 個`);
228
+ return results;
229
+ }
230
+ catch (error) {
231
+ // 使用自定義錯誤處理函數
232
+ const enhancedError = (0, error_handler_1.handleDouyinApiError)(error);
233
+ logger_1.infoLogger.error(`獲取用戶影片列表失敗: ${enhancedError.message}`);
234
+ throw enhancedError;
235
+ }
236
+ }
237
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../../src/douyin/info/user.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 抖音連結檢查模組
3
+ * 檢查文本是否包含抖音連結
4
+ *
5
+ * @remarks
6
+ * 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
7
+ * 需要驗證:確認函數是否與最新的抖音 URL 格式相容
8
+ */
9
+ /**
10
+ * 檢查文本是否包含抖音連結
11
+ * @param text 要檢查的文本
12
+ * @returns true 如果包含抖音連結,否則 false
13
+ *
14
+ * @remarks
15
+ * 改寫自原本存放於 src/parser/extract-links.ts 的功能
16
+ * 簡單封裝了 extractDouyinLinks 函數的結果檢查
17
+ */
18
+ export declare function containsDouyinLink(text: string): boolean;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * 抖音連結檢查模組
4
+ * 檢查文本是否包含抖音連結
5
+ *
6
+ * @remarks
7
+ * 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
8
+ * 需要驗證:確認函數是否與最新的抖音 URL 格式相容
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.containsDouyinLink = containsDouyinLink;
12
+ const extractDouyinLinks_1 = require("./extractDouyinLinks");
13
+ /**
14
+ * 檢查文本是否包含抖音連結
15
+ * @param text 要檢查的文本
16
+ * @returns true 如果包含抖音連結,否則 false
17
+ *
18
+ * @remarks
19
+ * 改寫自原本存放於 src/parser/extract-links.ts 的功能
20
+ * 簡單封裝了 extractDouyinLinks 函數的結果檢查
21
+ */
22
+ function containsDouyinLink(text) {
23
+ // 利用 extractDouyinLinks 函數提取連結,檢查是否有結果
24
+ const links = (0, extractDouyinLinks_1.extractDouyinLinks)(text);
25
+ return links.length > 0;
26
+ }
27
+ //# sourceMappingURL=containsDouyinLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containsDouyinLink.js","sourceRoot":"","sources":["../../../../src/douyin/parser/containsDouyinLink.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAaH,gDAIC;AAfD,6DAA0D;AAE1D;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,uCAAuC;IACvC,MAAM,KAAK,GAAG,IAAA,uCAAkB,EAAC,IAAI,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 連結提取模組
3
+ * 從文本中提取抖音連結
4
+ */
5
+ /**
6
+ * 從文本中提取所有潛在的抖音連結
7
+ * @param text 包含抖音連結的文本
8
+ * @returns string[] 提取出的抖音連結陣列
9
+ */
10
+ export declare function extractDouyinLinks(text: string): string[];
11
+ /**
12
+ * 從文本中提取特定類型的抖音連結
13
+ * @param text 包含抖音連結的文本
14
+ * @param typeName 連結類型名稱 (如 'standard', 'short' 等)
15
+ * @returns string[] 提取出的指定類型抖音連結陣列
16
+ */
17
+ export declare function extractDouyinLinksByType(text: string, typeName: string): string[];
18
+ /**
19
+ * 檢查文本是否包含抖音連結
20
+ * @param text 要檢查的文本
21
+ * @returns boolean 是否包含抖音連結
22
+ */
23
+ export declare function containsDouyinLink(text: string): boolean;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ // Copied from src/parser/extract-links.ts
3
+ // Original file path: src/parser/extract-links.ts
4
+ /**
5
+ * 連結提取模組
6
+ * 從文本中提取抖音連結
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.extractDouyinLinks = extractDouyinLinks;
10
+ exports.extractDouyinLinksByType = extractDouyinLinksByType;
11
+ exports.containsDouyinLink = containsDouyinLink;
12
+ const logger_1 = require("../../utils/logger"); // Updated path to shared utils logger
13
+ const link_patterns_1 = require("./link-patterns");
14
+ /**
15
+ * 從文本中提取所有潛在的抖音連結
16
+ * @param text 包含抖音連結的文本
17
+ * @returns string[] 提取出的抖音連結陣列
18
+ */
19
+ function extractDouyinLinks(text) {
20
+ if (!text || typeof text !== 'string') {
21
+ logger_1.parserLogger.warn('提取連結時收到無效文本');
22
+ return [];
23
+ }
24
+ // 使用合併正則表達式提取所有可能的抖音連結
25
+ const combinedPattern = (0, link_patterns_1.createCombinedPattern)();
26
+ const matches = text.match(combinedPattern);
27
+ // 如果沒有找到任何連結,返回空陣列
28
+ if (!matches) {
29
+ logger_1.parserLogger.debug('文本中未找到抖音連結');
30
+ return [];
31
+ }
32
+ // 過濾重複連結
33
+ const uniqueUrls = Array.from(new Set(matches));
34
+ logger_1.parserLogger.debug(`從文本中提取到 ${uniqueUrls.length} 個唯一抖音連結`);
35
+ return uniqueUrls;
36
+ }
37
+ /**
38
+ * 從文本中提取特定類型的抖音連結
39
+ * @param text 包含抖音連結的文本
40
+ * @param typeName 連結類型名稱 (如 'standard', 'short' 等)
41
+ * @returns string[] 提取出的指定類型抖音連結陣列
42
+ */
43
+ function extractDouyinLinksByType(text, typeName) {
44
+ if (!text || typeof text !== 'string') {
45
+ logger_1.parserLogger.warn('提取連結時收到無效文本');
46
+ return [];
47
+ }
48
+ // 查找指定類型的模式
49
+ const pattern = link_patterns_1.DOUYIN_LINK_PATTERNS.find(p => p.name === typeName);
50
+ if (!pattern) {
51
+ logger_1.parserLogger.warn(`未知的連結類型: ${typeName}`);
52
+ return [];
53
+ }
54
+ // 創建能夠全局匹配的正則表達式
55
+ const globalPattern = new RegExp(pattern.pattern.source, 'g');
56
+ const matches = text.match(globalPattern);
57
+ // 如果沒有找到任何連結,返回空陣列
58
+ if (!matches) {
59
+ logger_1.parserLogger.debug(`文本中未找到類型為 ${typeName} 的抖音連結`);
60
+ return [];
61
+ }
62
+ // 過濾重複連結
63
+ const uniqueUrls = Array.from(new Set(matches));
64
+ logger_1.parserLogger.debug(`從文本中提取到 ${uniqueUrls.length} 個類型為 ${typeName} 的唯一抖音連結`);
65
+ return uniqueUrls;
66
+ }
67
+ /**
68
+ * 檢查文本是否包含抖音連結
69
+ * @param text 要檢查的文本
70
+ * @returns boolean 是否包含抖音連結
71
+ */
72
+ function containsDouyinLink(text) {
73
+ if (!text || typeof text !== 'string') {
74
+ return false;
75
+ }
76
+ const combinedPattern = (0, link_patterns_1.createCombinedPattern)();
77
+ return combinedPattern.test(text);
78
+ }
79
+ //# sourceMappingURL=extract-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-links.js","sourceRoot":"","sources":["../../../../src/douyin/parser/extract-links.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,kDAAkD;AAClD;;;GAGG;;AAUH,gDAqBC;AAQD,4DA4BC;AAOD,gDAOC;AA/ED,+CAA4D,CAAC,sCAAsC;AACnG,mDAA8E;AAE9E;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,qBAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,uBAAuB;IACvB,MAAM,eAAe,GAAG,IAAA,qCAAqB,GAAE,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAE5C,mBAAmB;IACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS;IACT,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,qBAAM,CAAC,KAAK,CAAC,WAAW,UAAU,CAAC,MAAM,UAAU,CAAC,CAAC;IAErD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,IAAY,EAAE,QAAgB;IACrE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,qBAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY;IACZ,MAAM,OAAO,GAAG,oCAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAE1C,mBAAmB;IACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,KAAK,CAAC,aAAa,QAAQ,QAAQ,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS;IACT,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,qBAAM,CAAC,KAAK,CAAC,WAAW,UAAU,CAAC,MAAM,SAAS,QAAQ,UAAU,CAAC,CAAC;IAEtE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,eAAe,GAAG,IAAA,qCAAqB,GAAE,CAAC;IAChD,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 抖音連結提取模組
3
+ * 從文本中提取抖音連結
4
+ *
5
+ * @remarks
6
+ * 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
7
+ * 需要驗證:正則表達式是否匹配最新的抖音 URL 格式
8
+ */
9
+ /**
10
+ * 從文本中提取抖音連結
11
+ * @param text 可能包含抖音連結的文本
12
+ * @returns 提取出的抖音連結陣列
13
+ *
14
+ * @remarks
15
+ * 改寫自原本存放於 src/parser/extract-links.ts 的功能
16
+ * 使用正則表達式匹配不同的抖音網址格式
17
+ */
18
+ export declare function extractDouyinLinks(text: string): string[];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * 抖音連結提取模組
4
+ * 從文本中提取抖音連結
5
+ *
6
+ * @remarks
7
+ * 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
8
+ * 需要驗證:正則表達式是否匹配最新的抖音 URL 格式
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.extractDouyinLinks = extractDouyinLinks;
12
+ /**
13
+ * 抖音 URL 正則表達式模式
14
+ */
15
+ const PATTERNS = [
16
+ // 標準網頁連結,例如: https://www.douyin.com/video/7123456789
17
+ /https?:\/\/(?:www\.)?douyin\.com\/video\/(\d+)/g,
18
+ // 短連結,例如: https://v.douyin.com/abc123/
19
+ /https?:\/\/v\.douyin\.com\/([a-zA-Z0-9-]+)\/?/g,
20
+ // 移動端分享連結,例如: https://www.douyin.com/share/video/123456789
21
+ /https?:\/\/(?:www\.)?douyin\.com\/share\/video\/(\d+)/g,
22
+ // 筆記類型連結,例如: https://www.douyin.com/note/123456789
23
+ /https?:\/\/(?:www\.)?douyin\.com\/note\/(\d+)/g,
24
+ // 發現頁連結,例如: https://www.douyin.com/discover?modal_id=7123456789
25
+ /https?:\/\/(?:www\.)?douyin\.com\/discover\?.*modal_id=(\d+)/g,
26
+ // 帶參數的移動端連結,例如: https://www.iesdouyin.com/share/video/xxx/?region=CN&...
27
+ /https?:\/\/(?:www\.)?(?:douyin|iesdouyin)\.com\/.*\/.*\?.*(?:video_id|vid)=([^&]+)/g
28
+ // https://www.douyin.com/?vid=7489881436611218751&recommend=1
29
+ // /https?:\/\/(?:www\.)?douyin\.com\/\?.*vid=(\d+)/g,
30
+ ];
31
+ /**
32
+ * 從文本中提取抖音連結
33
+ * @param text 可能包含抖音連結的文本
34
+ * @returns 提取出的抖音連結陣列
35
+ *
36
+ * @remarks
37
+ * 改寫自原本存放於 src/parser/extract-links.ts 的功能
38
+ * 使用正則表達式匹配不同的抖音網址格式
39
+ */
40
+ function extractDouyinLinks(text) {
41
+ if (!text)
42
+ return [];
43
+ // 使用所有模式匹配文本
44
+ const results = [];
45
+ for (const pattern of PATTERNS) {
46
+ const matches = text.match(pattern);
47
+ if (matches) {
48
+ for (const match of matches) {
49
+ // 避免重複添加
50
+ if (!results.includes(match)) {
51
+ results.push(match);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ return results;
57
+ }
58
+ //# sourceMappingURL=extractDouyinLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractDouyinLinks.js","sourceRoot":"","sources":["../../../../src/douyin/parser/extractDouyinLinks.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAoCH,gDAkBC;AApDD;;GAEG;AACH,MAAM,QAAQ,GAAG;IACf,qDAAqD;IACrD,iDAAiD;IAEjD,uCAAuC;IACvC,gDAAgD;IAEhD,2DAA2D;IAC3D,wDAAwD;IAExD,mDAAmD;IACnD,gDAAgD;IAEhD,gEAAgE;IAChE,+DAA+D;IAE/D,yEAAyE;IACzE,qFAAqF;IACrF,+DAA+D;IAC/D,sDAAsD;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAErB,aAAa;IACb,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,SAAS;gBACT,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 連結解析模組
3
+ * 提供解析抖音各種格式連結的功能
4
+ */
5
+ import { ParseResult, ParseOptions } from '../../types';
6
+ import { extractDouyinLinks, containsDouyinLink } from './extract-links';
7
+ import { resolveLink, resolveShortUrl, createStandardUrl } from './resolve-links';
8
+ import { parseBatch, parseBatchWithStats } from './parse-batch';
9
+ import { getLinkType, extractVideoId } from './link-patterns';
10
+ export { extractDouyinLinks, containsDouyinLink, resolveLink, resolveShortUrl, parseBatch, parseBatchWithStats, getLinkType, extractVideoId, createStandardUrl };
11
+ /**
12
+ * 將單個抖音連結標準化
13
+ * @param url 抖音連結
14
+ * @returns Promise<ParseResult | null> 解析結果或 null
15
+ */
16
+ export declare function standardizeDouyinUrl(url: string): Promise<ParseResult | null>;
17
+ /**
18
+ * 解析抖音短連結並獲取標準 URL
19
+ * @param shortUrl 抖音短連結
20
+ * @returns Promise<string | null> 標準抖音影片 URL 或 null
21
+ */
22
+ export declare function parseDouyinShortUrl(shortUrl: string): Promise<string | null>;
23
+ /**
24
+ * 從文本中提取抖音連結
25
+ * @param text 包含抖音連結的文本
26
+ * @returns string[] 提取出的抖音連結陣列
27
+ */
28
+ export declare function extractDouyinUrls(text: string): string[];
29
+ /**
30
+ * 從文本中解析抖音連結,支援多種格式(標準URL、短連結、移動端分享連結等),並將其標準化。
31
+ * @param text 包含一個或多個抖音連結的文本字串
32
+ * @param options 解析選項
33
+ * @returns Promise<ParseResult[]> 解析結果陣列
34
+ */
35
+ export declare function parseDouyinLinks(text: string, options?: ParseOptions): Promise<ParseResult[]>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ // Copied from src/parser/index.ts
3
+ // Original file path: src/parser/index.ts
4
+ /**
5
+ * 連結解析模組
6
+ * 提供解析抖音各種格式連結的功能
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createStandardUrl = exports.extractVideoId = exports.getLinkType = exports.parseBatchWithStats = exports.parseBatch = exports.resolveShortUrl = exports.resolveLink = exports.containsDouyinLink = exports.extractDouyinLinks = void 0;
10
+ exports.standardizeDouyinUrl = standardizeDouyinUrl;
11
+ exports.parseDouyinShortUrl = parseDouyinShortUrl;
12
+ exports.extractDouyinUrls = extractDouyinUrls;
13
+ exports.parseDouyinLinks = parseDouyinLinks;
14
+ const logger_1 = require("../../utils/logger"); // Updated path to shared utils logger
15
+ const extract_links_1 = require("./extract-links");
16
+ Object.defineProperty(exports, "extractDouyinLinks", { enumerable: true, get: function () { return extract_links_1.extractDouyinLinks; } });
17
+ Object.defineProperty(exports, "containsDouyinLink", { enumerable: true, get: function () { return extract_links_1.containsDouyinLink; } });
18
+ const resolve_links_1 = require("./resolve-links");
19
+ Object.defineProperty(exports, "resolveLink", { enumerable: true, get: function () { return resolve_links_1.resolveLink; } });
20
+ Object.defineProperty(exports, "resolveShortUrl", { enumerable: true, get: function () { return resolve_links_1.resolveShortUrl; } });
21
+ Object.defineProperty(exports, "createStandardUrl", { enumerable: true, get: function () { return resolve_links_1.createStandardUrl; } });
22
+ const parse_batch_1 = require("./parse-batch");
23
+ Object.defineProperty(exports, "parseBatch", { enumerable: true, get: function () { return parse_batch_1.parseBatch; } });
24
+ Object.defineProperty(exports, "parseBatchWithStats", { enumerable: true, get: function () { return parse_batch_1.parseBatchWithStats; } });
25
+ const link_patterns_1 = require("./link-patterns");
26
+ Object.defineProperty(exports, "getLinkType", { enumerable: true, get: function () { return link_patterns_1.getLinkType; } });
27
+ Object.defineProperty(exports, "extractVideoId", { enumerable: true, get: function () { return link_patterns_1.extractVideoId; } });
28
+ /**
29
+ * 將單個抖音連結標準化
30
+ * @param url 抖音連結
31
+ * @returns Promise<ParseResult | null> 解析結果或 null
32
+ */
33
+ async function standardizeDouyinUrl(url) {
34
+ return await (0, resolve_links_1.resolveLink)(url);
35
+ }
36
+ /**
37
+ * 解析抖音短連結並獲取標準 URL
38
+ * @param shortUrl 抖音短連結
39
+ * @returns Promise<string | null> 標準抖音影片 URL 或 null
40
+ */
41
+ async function parseDouyinShortUrl(shortUrl) {
42
+ return await (0, resolve_links_1.resolveShortUrl)(shortUrl);
43
+ }
44
+ /**
45
+ * 從文本中提取抖音連結
46
+ * @param text 包含抖音連結的文本
47
+ * @returns string[] 提取出的抖音連結陣列
48
+ */
49
+ function extractDouyinUrls(text) {
50
+ return (0, extract_links_1.extractDouyinLinks)(text);
51
+ }
52
+ /**
53
+ * 從文本中解析抖音連結,支援多種格式(標準URL、短連結、移動端分享連結等),並將其標準化。
54
+ * @param text 包含一個或多個抖音連結的文本字串
55
+ * @param options 解析選項
56
+ * @returns Promise<ParseResult[]> 解析結果陣列
57
+ */
58
+ async function parseDouyinLinks(text, options = {}) {
59
+ // 提取連結
60
+ const urls = (0, extract_links_1.extractDouyinLinks)(text);
61
+ logger_1.parserLogger.info(`從文本中找到 ${urls.length} 個抖音連結`);
62
+ if (urls.length === 0) {
63
+ logger_1.parserLogger.warn('未找到任何抖音連結');
64
+ return [];
65
+ }
66
+ // 並行解析所有連結
67
+ const results = await (0, parse_batch_1.parseBatch)(urls, options);
68
+ return results;
69
+ }
70
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/douyin/parser/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,0CAA0C;AAC1C;;;GAGG;;;AA0BH,oDAEC;AAOD,kDAEC;AAOD,8CAEC;AAQD,4CAiBC;AArED,+CAA4D,CAAC,sCAAsC;AAEnG,mDAAyE;AAMvE,mGANO,kCAAkB,OAMP;AAClB,mGAP2B,kCAAkB,OAO3B;AANpB,mDAAkF;AAOhF,4FAPO,2BAAW,OAOP;AACX,gGARoB,+BAAe,OAQpB;AAKf,kGAbqC,iCAAiB,OAarC;AAZnB,+CAAgE;AAQ9D,2FARO,wBAAU,OAQP;AACV,oGATmB,iCAAmB,OASnB;AARrB,mDAA8D;AAS5D,4FATO,2BAAW,OASP;AACX,+FAVoB,8BAAc,OAUpB;AAIhB;;;;GAIG;AACI,KAAK,UAAU,oBAAoB,CAAC,GAAW;IACpD,OAAO,MAAM,IAAA,2BAAW,EAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,OAAO,MAAM,IAAA,+BAAe,EAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAA,kCAAkB,EAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,UAAwB,EAAE;IAE1B,OAAO;IACP,MAAM,IAAI,GAAG,IAAA,kCAAkB,EAAC,IAAI,CAAC,CAAC;IACtC,qBAAM,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,qBAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,WAAW;IACX,MAAM,OAAO,GAAG,MAAM,IAAA,wBAAU,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEhD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 抖音連結模式定義
3
+ * 定義各種抖音連結的正則表達式和處理方式
4
+ */
5
+ /**
6
+ * 連結模式介面
7
+ */
8
+ export interface LinkPattern {
9
+ name: string;
10
+ pattern: RegExp;
11
+ needsRedirect: boolean;
12
+ }
13
+ /**
14
+ * 抖音連結模式陣列
15
+ * 包含各種可能的抖音連結格式
16
+ */
17
+ export declare const DOUYIN_LINK_PATTERNS: LinkPattern[];
18
+ /**
19
+ * 創建用於在文本中查找所有抖音連結的正則表達式
20
+ * @returns RegExp 可以匹配任何抖音連結的正則表達式
21
+ */
22
+ export declare function createCombinedPattern(): RegExp;
23
+ /**
24
+ * 獲取抖音連結的類型
25
+ * @param url 抖音連結
26
+ * @returns LinkPattern | null 連結類型或 null (如果不匹配任何類型)
27
+ */
28
+ export declare function getLinkType(url: string): LinkPattern | null;
29
+ /**
30
+ * 從 URL 中提取影片 ID (如果可能)
31
+ * @param url 抖音連結
32
+ * @returns string | null 影片 ID 或 null (如果無法提取)
33
+ */
34
+ export declare function extractVideoId(url: string): string | null;