test-table-docs.mjs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // 直接实现函数,因为代码被打包了
  2. const UNPKG_BASE_URL = 'https://unpkg.com';
  3. const NPMMIRROR_BASE_URL = 'https://registry.npmmirror.com';
  4. function flattenDirectoryStructure(item, result = []) {
  5. result.push({
  6. path: item.path,
  7. type: item.type,
  8. size: item.size,
  9. });
  10. if (item.files && Array.isArray(item.files)) {
  11. for (const file of item.files) {
  12. flattenDirectoryStructure(file, result);
  13. }
  14. }
  15. return result;
  16. }
  17. async function fetchDirectoryListFromSource(baseUrl, packageName, version, path, isNpmMirror = false) {
  18. const url = isNpmMirror
  19. ? `${baseUrl}/${packageName}/${version}/files/${path}/?meta`
  20. : `${baseUrl}/${packageName}@${version}/${path}/?meta`;
  21. const response = await fetch(url, {
  22. headers: { Accept: 'application/json' },
  23. });
  24. if (!response.ok) {
  25. throw new Error(`获取目录列表失败: ${response.status} ${response.statusText}`);
  26. }
  27. const contentType = response.headers.get('content-type') || '';
  28. if (!contentType.includes('application/json')) {
  29. throw new Error(`API 返回了非 JSON 格式: ${contentType}`);
  30. }
  31. const data = await response.json();
  32. const normalizeType = (item) => {
  33. const path = item.path;
  34. if (path.endsWith('/')) return { path, type: 'directory' };
  35. if (item.type && item.type.includes('/')) return { path, type: 'file' };
  36. if (item.type === 'directory') return { path, type: 'directory' };
  37. return { path, type: 'file' };
  38. };
  39. if (Array.isArray(data)) {
  40. return data.map(normalizeType);
  41. }
  42. if (data && typeof data === 'object' && 'files' in data) {
  43. if (Array.isArray(data.files)) {
  44. const flattened = [];
  45. for (const item of data.files) {
  46. flattenDirectoryStructure(item, flattened);
  47. }
  48. return flattened.map(normalizeType);
  49. }
  50. return [];
  51. }
  52. if (data && typeof data === 'object' && 'path' in data) {
  53. const singleItem = data;
  54. if (singleItem.files && Array.isArray(singleItem.files)) {
  55. const flattened = [];
  56. flattenDirectoryStructure(singleItem, flattened);
  57. return flattened.map(normalizeType);
  58. }
  59. return [normalizeType(singleItem)];
  60. }
  61. throw new Error('无法解析目录列表数据格式');
  62. }
  63. async function fetchFileContentFromSource(baseUrl, packageName, version, filePath, isNpmMirror = false) {
  64. const url = isNpmMirror
  65. ? `${baseUrl}/${packageName}/${version}/files/${filePath}`
  66. : `${baseUrl}/${packageName}@${version}/${filePath}`;
  67. const response = await fetch(url, {
  68. headers: { Accept: 'text/plain, application/json, */*' },
  69. });
  70. if (!response.ok) {
  71. throw new Error(`获取文件失败: ${response.status} ${response.statusText}`);
  72. }
  73. const content = await response.text();
  74. if (content.trim().startsWith('<!DOCTYPE html>') || content.includes('npmmirror 镜像站')) {
  75. throw new Error('返回了 HTML 错误页面');
  76. }
  77. return content;
  78. }
  79. const packageName = '@douyinfe/semi-ui';
  80. const version = '2.89.2-alpha.3';
  81. const componentName = 'table';
  82. async function testUnpkg() {
  83. console.log('\n' + '='.repeat(80));
  84. console.log('测试 UNPKG 数据源');
  85. console.log('='.repeat(80));
  86. try {
  87. console.log('\n1. 获取目录列表...');
  88. const files = await fetchDirectoryListFromSource(
  89. UNPKG_BASE_URL,
  90. packageName,
  91. version,
  92. 'content',
  93. false
  94. );
  95. console.log(` 找到 ${files.length} 个文件/目录`);
  96. const tableFiles = files.filter((file) => {
  97. const path = file.path.toLowerCase();
  98. return path.includes(componentName) && file.type === 'file';
  99. });
  100. console.log(` 找到 ${tableFiles.length} 个 table 相关文件:`);
  101. tableFiles.forEach((file, index) => {
  102. console.log(` ${index + 1}. ${file.path} (${file.type})`);
  103. });
  104. if (tableFiles.length > 0) {
  105. console.log('\n2. 获取文档内容...');
  106. for (const file of tableFiles.slice(0, 2)) { // 只获取前两个文件
  107. const filePath = file.path.startsWith('/') ? file.path.slice(1) : file.path;
  108. console.log(`\n 文件: ${file.path}`);
  109. console.log(' ' + '-'.repeat(76));
  110. try {
  111. const content = await fetchFileContentFromSource(
  112. UNPKG_BASE_URL,
  113. packageName,
  114. version,
  115. filePath,
  116. false
  117. );
  118. console.log(` 内容长度: ${content.length} 字符`);
  119. console.log(` 内容预览 (前500字符):`);
  120. console.log(' ' + content.substring(0, 500).replace(/\n/g, '\n '));
  121. console.log(' ...');
  122. } catch (error) {
  123. console.error(` 获取失败: ${error.message}`);
  124. }
  125. }
  126. }
  127. } catch (error) {
  128. console.error(`\n错误: ${error.message}`);
  129. console.error(error.stack);
  130. }
  131. }
  132. async function testNpmMirror() {
  133. console.log('\n' + '='.repeat(80));
  134. console.log('测试 NPMMIRROR 数据源');
  135. console.log('='.repeat(80));
  136. try {
  137. console.log('\n1. 获取目录列表...');
  138. const files = await fetchDirectoryListFromSource(
  139. NPMMIRROR_BASE_URL,
  140. packageName,
  141. version,
  142. 'content',
  143. true
  144. );
  145. console.log(` 找到 ${files.length} 个文件/目录`);
  146. const tableFiles = files.filter((file) => {
  147. const path = file.path.toLowerCase();
  148. return path.includes(componentName) && file.type === 'file';
  149. });
  150. console.log(` 找到 ${tableFiles.length} 个 table 相关文件:`);
  151. tableFiles.forEach((file, index) => {
  152. console.log(` ${index + 1}. ${file.path} (${file.type})`);
  153. });
  154. if (tableFiles.length > 0) {
  155. console.log('\n2. 获取文档内容...');
  156. for (const file of tableFiles.slice(0, 2)) { // 只获取前两个文件
  157. const filePath = file.path.startsWith('/') ? file.path.slice(1) : file.path;
  158. console.log(`\n 文件: ${file.path}`);
  159. console.log(' ' + '-'.repeat(76));
  160. try {
  161. const content = await fetchFileContentFromSource(
  162. NPMMIRROR_BASE_URL,
  163. packageName,
  164. version,
  165. filePath,
  166. true
  167. );
  168. console.log(` 内容长度: ${content.length} 字符`);
  169. console.log(` 内容预览 (前500字符):`);
  170. console.log(' ' + content.substring(0, 500).replace(/\n/g, '\n '));
  171. console.log(' ...');
  172. } catch (error) {
  173. console.error(` 获取失败: ${error.message}`);
  174. }
  175. }
  176. } else {
  177. console.log('\n 注意: 未找到 table 文件,可能是嵌套结构未完全扁平化');
  178. console.log(` 前10个文件/目录示例:`);
  179. files.slice(0, 10).forEach((file, index) => {
  180. console.log(` ${index + 1}. ${file.path} (${file.type})`);
  181. });
  182. }
  183. } catch (error) {
  184. console.error(`\n错误: ${error.message}`);
  185. console.error(error.stack);
  186. }
  187. }
  188. async function compareSources() {
  189. console.log('\n' + '='.repeat(80));
  190. console.log('对比两个数据源');
  191. console.log('='.repeat(80));
  192. const filePath = 'content/show/table/index.md';
  193. try {
  194. console.log('\n同时从两个数据源获取文件...');
  195. const [unpkgResult, npmmirrorResult] = await Promise.allSettled([
  196. fetchFileContentFromSource(UNPKG_BASE_URL, packageName, version, filePath, false),
  197. fetchFileContentFromSource(NPMMIRROR_BASE_URL, packageName, version, filePath, true),
  198. ]);
  199. console.log('\nUNPKG 结果:');
  200. if (unpkgResult.status === 'fulfilled') {
  201. const content = unpkgResult.value;
  202. console.log(` ✓ 成功获取,内容长度: ${content.length} 字符`);
  203. console.log(` 预览: ${content.substring(0, 100).replace(/\n/g, ' ')}...`);
  204. } else {
  205. console.log(` ✗ 失败: ${unpkgResult.reason?.message || '未知错误'}`);
  206. }
  207. console.log('\nNPMMIRROR 结果:');
  208. if (npmmirrorResult.status === 'fulfilled') {
  209. const content = npmmirrorResult.value;
  210. console.log(` ✓ 成功获取,内容长度: ${content.length} 字符`);
  211. console.log(` 预览: ${content.substring(0, 100).replace(/\n/g, ' ')}...`);
  212. } else {
  213. console.log(` ✗ 失败: ${npmmirrorResult.reason?.message || '未知错误'}`);
  214. }
  215. if (unpkgResult.status === 'fulfilled' && npmmirrorResult.status === 'fulfilled') {
  216. const unpkgContent = unpkgResult.value;
  217. const npmmirrorContent = npmmirrorResult.value;
  218. console.log('\n对比结果:');
  219. console.log(` 内容长度差异: ${Math.abs(unpkgContent.length - npmmirrorContent.length)} 字符`);
  220. console.log(` 内容是否相同: ${unpkgContent === npmmirrorContent ? '是' : '否'}`);
  221. if (unpkgContent !== npmmirrorContent) {
  222. // 找出第一个不同的位置
  223. let diffIndex = 0;
  224. const minLength = Math.min(unpkgContent.length, npmmirrorContent.length);
  225. for (let i = 0; i < minLength; i++) {
  226. if (unpkgContent[i] !== npmmirrorContent[i]) {
  227. diffIndex = i;
  228. break;
  229. }
  230. }
  231. console.log(` 第一个差异位置: 第 ${diffIndex} 个字符`);
  232. console.log(` UNPKG 片段: ${unpkgContent.substring(diffIndex, diffIndex + 50)}`);
  233. console.log(` NPMMIRROR 片段: ${npmmirrorContent.substring(diffIndex, diffIndex + 50)}`);
  234. }
  235. }
  236. } catch (error) {
  237. console.error(`\n对比失败: ${error.message}`);
  238. }
  239. }
  240. async function main() {
  241. console.log('Table 组件文档测试脚本');
  242. console.log(`包名: ${packageName}`);
  243. console.log(`版本: ${version}`);
  244. console.log(`组件: ${componentName}`);
  245. await testUnpkg();
  246. await testNpmMirror();
  247. await compareSources();
  248. console.log('\n' + '='.repeat(80));
  249. console.log('测试完成');
  250. console.log('='.repeat(80));
  251. }
  252. main().catch(console.error);