yuque-dl 1.0.22 → 1.0.24
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/.eslintrc.cjs +21 -0
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/index-852c3568.js +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/es/cli.js +1 -1
- package/dist/es/index-16978a9a.js +1 -0
- package/dist/es/index.js +1 -1
- package/eslint.log +0 -0
- package/package.json +3 -2
- package/dist/cjs/index-fe7237f7.js +0 -1
- package/dist/es/index-573d9cde.js +0 -1
package/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
node: true,
|
|
4
|
+
},
|
|
5
|
+
parser: '@typescript-eslint/parser',
|
|
6
|
+
plugins: [
|
|
7
|
+
'@typescript-eslint',
|
|
8
|
+
],
|
|
9
|
+
extends: [
|
|
10
|
+
'eslint:recommended',
|
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
|
12
|
+
],
|
|
13
|
+
rules: {
|
|
14
|
+
semi: ['error', 'never'],
|
|
15
|
+
'no-console': 'off',
|
|
16
|
+
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
|
|
17
|
+
// TODO
|
|
18
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
19
|
+
'@typescript-eslint/no-non-null-assertion': 'off'
|
|
20
|
+
},
|
|
21
|
+
}
|
package/dist/cjs/cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("node:fs"),r=require("cac"),o=require("./index-
|
|
1
|
+
"use strict";var e=require("node:fs"),r=require("cac"),o=require("./index-852c3568.js");require("node:fs/promises"),require("pull-md-img"),require("ora"),require("cli-progress"),require("log4js"),require("axios"),require("rand-user-agent");var n="undefined"!=typeof document?document.currentScript:null;const i=r.cac("yuque-dl"),{version:t}=JSON.parse(e.readFileSync(new URL("../../package.json","undefined"==typeof document?require("url").pathToFileURL(__filename).href:n&&n.src||new URL("cli.js",document.baseURI).href)).toString());i.command("<url>","语雀知识库url").option("-d, --distDir <dir>","下载的目录 eg: -d download",{default:"download"}).option("-i, --ignoreImg","忽略图片不下载",{default:!1}).option("-t, --token <token>",'语雀的cookie "_yuque_session"').action((async(e,r)=>{try{await o.main(e,r)}catch(e){o.logger.error(e.message||"unknown exception")}})),i.help(),i.version(t);try{i.parse()}catch(e){o.logger.error(e.message||"unknown exception"),process.exit(1)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var t=require("node:fs/promises"),e=require("pull-md-img"),r=require("ora"),o=require("cli-progress"),s=require("log4js"),i=require("axios"),n=require("rand-user-agent");var a,c,l=(s.configure({appenders:{cheese:{type:"console",layout:{type:"pattern",pattern:"%[%c [%p]:%] %m%n"}}},categories:{default:{appenders:["cheese"],level:"trace"}}}),s.getLogger("yuque-dl"));class u{constructor(t,e){this.bookPath="",this.progressFilePath="",this.progressInfo=[],this.curr=0,this.total=0,this.isDownloadInterrupted=!1,this.bar=null,this.completePromise=null,this.bookPath=t,this.progressFilePath=`${t}/progress.json`,this.total=e}async init(){this.progressInfo=await this.getProgress(),this.curr=this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&(this.isDownloadInterrupted=!0,l.info("根据上次数据继续断点下载")),this.bar=new o.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},o.Presets.legacy),this.bar.start(this.total,this.curr))}async getProgress(){let e=[];try{const r=await t.readFile(this.progressFilePath,{encoding:"utf8"});e=JSON.parse(r)}catch(r){r&&"ENOENT"===r.code&&await t.writeFile(this.progressFilePath,JSON.stringify(e),{encoding:"utf8"})}return e}async updateProgress(e,r){this.curr=this.curr+1,r&&(this.progressInfo.push(e),await t.writeFile(this.progressFilePath,JSON.stringify(this.progressInfo),{encoding:"utf8"})),this.bar&&(this.bar.update(this.curr),this.curr>=this.total&&(this.bar.stop(),console.log("")))}pause(){this.bar&&this.bar.stop()}continue(){this.clearLine(2),this.bar?.start(this.total,this.curr)}clearLine(t){if(!(t<=0)&&"function"==typeof process?.stderr?.cursorTo){process.stderr.cursorTo(0);for(let e=0;e<t;e++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}class d{constructor(t){this.summaryInfo=t}async genFile(){const{bookName:e,bookDesc:r,bookPath:o,uuidMap:s}=this.summaryInfo;let i=`# ${e}\n\n`;r&&(i+=`> ${r}\n\n`);let n=i;const a=[];s.forEach((t=>{const e=t.toc,r=e.parent_uuid,o=this.findTree(a,r),s={text:e.title.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/,""),id:e.uuid,level:1,type:""},i=e.type.toLocaleLowerCase();"title"===i||""!==e.child_uuid?(s.type="title","boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),s.level=o.level+1,o.children.push(s)):(s.level=1,a.push(s))):(s.type="link",s.link="link"===i?t.toc.url:t.path,"boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),s.level=o.level+1,o.children.push(s)):(s.level=1,a.push(s)))}));n+=this.genSummaryContent(a,"");try{await t.writeFile(`${o}/SUMMARY.md`,n)}catch(t){l.error("Generate Summary Error")}}genSummaryContent(t,e){for(const r of t){if("title"===r.type)e+=`\n${"".padStart(r.level+1,"#")} ${r.text}\n\n`;else if("link"===r.type){const t=r.link?r.link.replace(/\s/g,"%20"):r.link;e+=`- [${r.text}](${t})\n`}Array.isArray(r.children)&&(e+=this.genSummaryContent(r.children,""))}return e}findIdItem(t,e){if(t.id===e)return t;if(t.children){const r=this.findTree(t.children,e);if(r)return r}return!1}findTree(t,e){if(!e)return!1;for(const r of t){const t=this.findIdItem(r,e);if(t)return t}return!1}}!function(t){t.TITLE="title",t.LINK="link",t.DOC="doc"}(a||(a={})),function(t){t.BOARD="board",t.TABLE="table",t.SHEET="sheet",t.DOC="doc"}(c||(c={}));const h=new Map([[c.BOARD,"画板类型"],[c.TABLE,"数据表类型"],[c.SHEET,"表格类型"],[c.DOC,"文档类型"]]);function p({browser:t="chrome",os:e="mac os",device:r="desktop"}){r=r.toLowerCase(),t=t.toLowerCase(),e=e.toLowerCase();let o=n(r,t,e);if("chrome"===t)for(;o.includes("Chrome-Lighthouse")||o.includes("Gener8")||o.includes("HeadlessChrome")||o.includes("SMTBot");)o=n(r,t,e);if("safari"===t)for(;o.includes("Applebot");)o=n(r,t,e);return o}function g(t){const e={"user-agent":p({browser:"chrome",device:"desktop"})};return t&&(e.cookie=`_yuque_session=${t}`),e}const f=t=>{const{articleUrl:e,bookId:r,token:o}=t;let s=`https://www.yuque.com/api/docs/${e}`;const n={book_id:String(r),merge_dynamic_data:String(!1),mode:"markdown"},a=new URLSearchParams(n).toString();return s=`${s}?${a}`,i.get(s,{headers:g(o)}).then((({data:t,status:e})=>({apiUrl:s,httpStatus:e,response:t})))};async function w(o,s,i){const{bookId:n,itemUrl:a,savePath:l,saveFilePath:u,uuid:d,articleUrl:p,articleTitle:g,ignoreImg:w}=o,{httpStatus:m,apiUrl:b,response:$}=await f({articleUrl:a,bookId:n,token:i}),k=$?.data?.type?.toLocaleLowerCase();if([c.BOARD,c.SHEET,c.TABLE].includes(k)){const t=h.get(k);throw new Error(`download article Error: 暂不支持“${t}”的文档`)}if("string"!=typeof $?.data?.sourcecode)throw new Error(`download article Error: ${b}, http status ${m}`);let y=$.data.sourcecode;if(!w){s.pause(),console.log("");const t=r({text:`下载 "${g}" 的图片中...`});t.start();try{y=await e.run(y,{dist:l,imgDir:`./img/${d}`,isIgnoreConsole:!0})}catch(t){let e=`download article image Error: ${t.message}`;throw t.error&&t.url&&(e=`download article image Error ${t.url}: ${t.error?.message}`),new Error(e)}finally{t.stop(),s.continue()}}y=y.replace(/<br(\s?)\/>/gm,"\n"),g&&(y=`# ${g}\n\x3c!--page header--\x3e\n\n${y}\n\n`),p&&(y+=`\x3c!--page footer--\x3e\n- 原文: <${p}>`);try{return await t.writeFile(u,y),!0}catch(t){throw new Error(`download article Error ${p}: ${t.message}`)}}function m(t){if(!t)return"";return t.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"")}exports.downloadArticle=w,exports.logger=l,exports.main=async function(e,r){const{bookId:o,tocList:s,bookName:n,bookDesc:c,bookSlug:h}=await((t,e)=>{const r=/decodeURIComponent\("(.+)"\)\);/m;return i.get(t,{headers:g(e)}).then((({data:t="",status:e})=>200===e?t:"")).then((t=>{const e=r.exec(t)??"";if(!e[1])return{};const o=JSON.parse(decodeURIComponent(e[1]));return o.book?{bookId:o.book.id,bookSlug:o.book.slug,tocList:o.book.toc||[],bookName:o.book.name||"",bookDesc:o.book.description||""}:{}}))})(e,r.token);if(!o)throw new Error("No found book id");if(!s||0===s.length)throw new Error("No found toc list");const p=`${r.distDir}/${n?m(n):o}`;await t.mkdir(p,{recursive:!0});const f=s.length,b=new u(p,f);if(await b.init(),b.curr===f)return b.bar&&b.bar.stop(),void l.info(`√ 已完成: ${process.cwd()}/${p}`);const $=new Map;b.isDownloadInterrupted&&b.progressInfo.forEach((t=>{$.set(t.toc.uuid,t)}));const k=e.replace(new RegExp(`(.*?/${h}).*`),"$1");await async function(e){const{articleUrlPrefix:r,total:o,uuidMap:s,tocList:i,bookPath:n,bookId:c,progressBar:u,options:d}=e;let h=0,p=0,g=0;const f=[],b=[];for(let e=0;e<o;e++){const o=i[e];if("string"!=typeof o.type)continue;if(s.get(o.uuid))continue;const l=o.type.toLocaleLowerCase();if(l===a.TITLE||""!==o.child_uuid||l===a.LINK){let e=o;const r=[],i=[];for(;e;)r.unshift(m(e.title)),i.unshift(e.uuid),e=s.get(e.parent_uuid)?s.get(e.parent_uuid).toc:void 0;const c={path:r.join("/"),pathTitleList:r,pathIdList:i,toc:o};l===a.LINK?(g+=1,b.push(c)):await t.mkdir(`${n}/${r.join("/")}`,{recursive:!0}),s.set(o.uuid,c),await u.updateProgress(c,l!==a.LINK)}else if(o.url){p+=1;let t={path:"",pathTitleList:[],pathIdList:[]};s.get(o.parent_uuid)&&(t=s.get(o.parent_uuid));const e=m(o.title),i=[...t.pathTitleList,`${e}.md`],a=[...t.pathIdList,o.uuid],l={path:i.join("/"),pathTitleList:i,pathIdList:a,toc:o};let g=!0;const b=`${r}/${o.url}`;try{await w({bookId:c,itemUrl:o.url,savePath:`${n}/${t.path}`,saveFilePath:`${n}/${l.path}`,uuid:o.uuid,articleUrl:b,articleTitle:o.title,ignoreImg:d.ignoreImg},u,d.token)}catch(t){g=!1,h+=1,f.push({articleUrl:b,errItem:l,errMsg:t.message,err:t})}s.set(o.uuid,l),await u.updateProgress(l,g)}}if(g>0){l.warn("该知识库存在以下外链文章");for(const t of b)l.warn(`———— ✕ ${t.path} ${t.toc.url}`)}if(h>0){l.error(`本次执行总数${p}篇,✕ 失败${h}篇`);for(const t of f)l.error(`${t.errItem.path} ———— ${t.articleUrl}`),l.error(`———— ✕ ${t.errMsg}`);l.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}}({articleUrlPrefix:k,total:f,uuidMap:$,tocList:s,bookPath:p,bookId:o,progressBar:b,options:r});const y=new d({bookPath:p,bookName:n,bookDesc:c,uuidMap:$});await y.genFile();const I=process.cwd();l.info(`√ 生成目录 ${I}/${p}/SUMMARY.md`),b.curr===f&&l.info(`√ 已完成: ${I}/${p}`),process.exit(0)};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("node:fs/promises"),require("pull-md-img"),require("ora");var r=require("./index-
|
|
1
|
+
"use strict";require("node:fs/promises"),require("pull-md-img"),require("ora");var r=require("./index-852c3568.js");require("cli-progress"),require("log4js"),require("axios"),require("rand-user-agent"),exports.downloadArticle=r.downloadArticle,exports.main=r.main;
|
package/dist/es/cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as o}from"node:fs";import{cac as r}from"cac";import{m as e,l as i}from"./index-
|
|
1
|
+
import{readFileSync as o}from"node:fs";import{cac as r}from"cac";import{m as e,l as i}from"./index-16978a9a.js";import"node:fs/promises";import"pull-md-img";import"ora";import"cli-progress";import"log4js";import"axios";import"rand-user-agent";const t=r("yuque-dl"),{version:n}=JSON.parse(o(new URL("../../package.json",import.meta.url)).toString());t.command("<url>","语雀知识库url").option("-d, --distDir <dir>","下载的目录 eg: -d download",{default:"download"}).option("-i, --ignoreImg","忽略图片不下载",{default:!1}).option("-t, --token <token>",'语雀的cookie "_yuque_session"').action((async(o,r)=>{try{await e(o,r)}catch(o){i.error(o.message||"unknown exception")}})),t.help(),t.version(n);try{t.parse()}catch(o){i.error(o.message||"unknown exception"),process.exit(1)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t,{writeFile as e,mkdir as r}from"node:fs/promises";import o from"pull-md-img";import s from"ora";import i from"cli-progress";import n from"log4js";import a from"axios";import c from"rand-user-agent";var l,u,d=(n.configure({appenders:{cheese:{type:"console",layout:{type:"pattern",pattern:"%[%c [%p]:%] %m%n"}}},categories:{default:{appenders:["cheese"],level:"trace"}}}),n.getLogger("yuque-dl"));class h{constructor(t,e){this.bookPath="",this.progressFilePath="",this.progressInfo=[],this.curr=0,this.total=0,this.isDownloadInterrupted=!1,this.bar=null,this.completePromise=null,this.bookPath=t,this.progressFilePath=`${t}/progress.json`,this.total=e}async init(){this.progressInfo=await this.getProgress(),this.curr=this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&(this.isDownloadInterrupted=!0,d.info("根据上次数据继续断点下载")),this.bar=new i.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},i.Presets.legacy),this.bar.start(this.total,this.curr))}async getProgress(){let e=[];try{const r=await t.readFile(this.progressFilePath,{encoding:"utf8"});e=JSON.parse(r)}catch(r){r&&"ENOENT"===r.code&&await t.writeFile(this.progressFilePath,JSON.stringify(e),{encoding:"utf8"})}return e}async updateProgress(e,r){this.curr=this.curr+1,r&&(this.progressInfo.push(e),await t.writeFile(this.progressFilePath,JSON.stringify(this.progressInfo),{encoding:"utf8"})),this.bar&&(this.bar.update(this.curr),this.curr>=this.total&&(this.bar.stop(),console.log("")))}pause(){this.bar&&this.bar.stop()}continue(){this.clearLine(2),this.bar?.start(this.total,this.curr)}clearLine(t){if(!(t<=0)&&"function"==typeof process?.stderr?.cursorTo){process.stderr.cursorTo(0);for(let e=0;e<t;e++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}class p{constructor(t){this.summaryInfo=t}async genFile(){const{bookName:e,bookDesc:r,bookPath:o,uuidMap:s}=this.summaryInfo;let i=`# ${e}\n\n`;r&&(i+=`> ${r}\n\n`);let n=i;const a=[];s.forEach((t=>{const e=t.toc,r=e.parent_uuid,o=this.findTree(a,r),s={text:e.title.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/,""),id:e.uuid,level:1,type:""},i=e.type.toLocaleLowerCase();"title"===i||""!==e.child_uuid?(s.type="title","boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),s.level=o.level+1,o.children.push(s)):(s.level=1,a.push(s))):(s.type="link",s.link="link"===i?t.toc.url:t.path,"boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),s.level=o.level+1,o.children.push(s)):(s.level=1,a.push(s)))}));n+=this.genSummaryContent(a,"");try{await t.writeFile(`${o}/SUMMARY.md`,n)}catch(t){d.error("Generate Summary Error")}}genSummaryContent(t,e){for(const r of t){if("title"===r.type)e+=`\n${"".padStart(r.level+1,"#")} ${r.text}\n\n`;else if("link"===r.type){const t=r.link?r.link.replace(/\s/g,"%20"):r.link;e+=`- [${r.text}](${t})\n`}Array.isArray(r.children)&&(e+=this.genSummaryContent(r.children,""))}return e}findIdItem(t,e){if(t.id===e)return t;if(t.children){const r=this.findTree(t.children,e);if(r)return r}return!1}findTree(t,e){if(!e)return!1;for(const r of t){const t=this.findIdItem(r,e);if(t)return t}return!1}}!function(t){t.TITLE="title",t.LINK="link",t.DOC="doc"}(l||(l={})),function(t){t.BOARD="board",t.TABLE="table",t.SHEET="sheet",t.DOC="doc"}(u||(u={}));const f=new Map([[u.BOARD,"画板类型"],[u.TABLE,"数据表类型"],[u.SHEET,"表格类型"],[u.DOC,"文档类型"]]);function g({browser:t="chrome",os:e="mac os",device:r="desktop"}){r=r.toLowerCase(),t=t.toLowerCase(),e=e.toLowerCase();let o=c(r,t,e);if("chrome"===t)for(;o.includes("Chrome-Lighthouse")||o.includes("Gener8")||o.includes("HeadlessChrome")||o.includes("SMTBot");)o=c(r,t,e);if("safari"===t)for(;o.includes("Applebot");)o=c(r,t,e);return o}function m(t){const e={"user-agent":g({browser:"chrome",device:"desktop"})};return t&&(e.cookie=`_yuque_session=${t}`),e}const w=t=>{const{articleUrl:e,bookId:r,token:o}=t;let s=`https://www.yuque.com/api/docs/${e}`;const i={book_id:String(r),merge_dynamic_data:String(!1),mode:"markdown"},n=new URLSearchParams(i).toString();return s=`${s}?${n}`,a.get(s,{headers:m(o)}).then((({data:t,status:e})=>({apiUrl:s,httpStatus:e,response:t})))};async function b(t,r,i){const{bookId:n,itemUrl:a,savePath:c,saveFilePath:l,uuid:d,articleUrl:h,articleTitle:p,ignoreImg:g}=t,{httpStatus:m,apiUrl:b,response:$}=await w({articleUrl:a,bookId:n,token:i}),y=$?.data?.type?.toLocaleLowerCase();if([u.BOARD,u.SHEET,u.TABLE].includes(y)){const t=f.get(y);throw new Error(`download article Error: 暂不支持“${t}”的文档`)}if("string"!=typeof $?.data?.sourcecode)throw new Error(`download article Error: ${b}, http status ${m}`);let k=$.data.sourcecode;if(!g){r.pause(),console.log("");const t=s({text:`下载 "${p}" 的图片中...`});t.start();try{k=await o.run(k,{dist:c,imgDir:`./img/${d}`,isIgnoreConsole:!0})}catch(t){let e=`download article image Error: ${t.message}`;throw t.error&&t.url&&(e=`download article image Error ${t.url}: ${t.error?.message}`),new Error(e)}finally{t.stop(),r.continue()}}k=k.replace(/<br(\s?)\/>/gm,"\n"),p&&(k=`# ${p}\n\x3c!--page header--\x3e\n\n${k}\n\n`),h&&(k+=`\x3c!--page footer--\x3e\n- 原文: <${h}>`);try{return await e(l,k),!0}catch(t){throw new Error(`download article Error ${h}: ${t.message}`)}}function $(t){if(!t)return"";return t.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"")}async function y(t,e){const{bookId:o,tocList:s,bookName:i,bookDesc:n,bookSlug:c}=await((t,e)=>{const r=/decodeURIComponent\("(.+)"\)\);/m;return a.get(t,{headers:m(e)}).then((({data:t="",status:e})=>200===e?t:"")).then((t=>{const e=r.exec(t)??"";if(!e[1])return{};const o=JSON.parse(decodeURIComponent(e[1]));return o.book?{bookId:o.book.id,bookSlug:o.book.slug,tocList:o.book.toc||[],bookName:o.book.name||"",bookDesc:o.book.description||""}:{}}))})(t,e.token);if(!o)throw new Error("No found book id");if(!s||0===s.length)throw new Error("No found toc list");const u=`${e.distDir}/${i?$(i):o}`;await r(u,{recursive:!0});const f=s.length,g=new h(u,f);if(await g.init(),g.curr===f)return g.bar&&g.bar.stop(),void d.info(`√ 已完成: ${process.cwd()}/${u}`);const w=new Map;g.isDownloadInterrupted&&g.progressInfo.forEach((t=>{w.set(t.toc.uuid,t)}));const y=t.replace(new RegExp(`(.*?/${c}).*`),"$1");await async function(t){const{articleUrlPrefix:e,total:o,uuidMap:s,tocList:i,bookPath:n,bookId:a,progressBar:c,options:u}=t;let h=0,p=0,f=0;const g=[],m=[];for(let t=0;t<o;t++){const o=i[t];if("string"!=typeof o.type)continue;if(s.get(o.uuid))continue;const d=o.type.toLocaleLowerCase();if(d===l.TITLE||""!==o.child_uuid||d===l.LINK){let t=o;const e=[],i=[];for(;t;)e.unshift($(t.title)),i.unshift(t.uuid),t=s.get(t.parent_uuid)?s.get(t.parent_uuid).toc:void 0;const a={path:e.join("/"),pathTitleList:e,pathIdList:i,toc:o};d===l.LINK?(f+=1,m.push(a)):await r(`${n}/${e.join("/")}`,{recursive:!0}),s.set(o.uuid,a),await c.updateProgress(a,d!==l.LINK)}else if(o.url){p+=1;let t={path:"",pathTitleList:[],pathIdList:[]};s.get(o.parent_uuid)&&(t=s.get(o.parent_uuid));const r=$(o.title),i=[...t.pathTitleList,`${r}.md`],l=[...t.pathIdList,o.uuid],d={path:i.join("/"),pathTitleList:i,pathIdList:l,toc:o};let f=!0;const m=`${e}/${o.url}`;try{await b({bookId:a,itemUrl:o.url,savePath:`${n}/${t.path}`,saveFilePath:`${n}/${d.path}`,uuid:o.uuid,articleUrl:m,articleTitle:o.title,ignoreImg:u.ignoreImg},c,u.token)}catch(t){f=!1,h+=1,g.push({articleUrl:m,errItem:d,errMsg:t.message,err:t})}s.set(o.uuid,d),await c.updateProgress(d,f)}}if(f>0){d.warn("该知识库存在以下外链文章");for(const t of m)d.warn(`———— ✕ ${t.path} ${t.toc.url}`)}if(h>0){d.error(`本次执行总数${p}篇,✕ 失败${h}篇`);for(const t of g)d.error(`${t.errItem.path} ———— ${t.articleUrl}`),d.error(`———— ✕ ${t.errMsg}`);d.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}}({articleUrlPrefix:y,total:f,uuidMap:w,tocList:s,bookPath:u,bookId:o,progressBar:g,options:e});const k=new p({bookPath:u,bookName:i,bookDesc:n,uuidMap:w});await k.genFile();const I=process.cwd();d.info(`√ 生成目录 ${I}/${u}/SUMMARY.md`),g.curr===f&&d.info(`√ 已完成: ${I}/${u}`),process.exit(0)}export{b as d,d as l,y as m};
|
package/dist/es/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"node:fs/promises";import"pull-md-img";import"ora";export{d as downloadArticle,m as main}from"./index-
|
|
1
|
+
import"node:fs/promises";import"pull-md-img";import"ora";export{d as downloadArticle,m as main}from"./index-16978a9a.js";import"cli-progress";import"log4js";import"axios";import"rand-user-agent";
|
package/eslint.log
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuque-dl",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"description": "yuque 知识库下载",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"build:types": "tsc --emitDeclarationOnly --outDir types -p tsconfig.base.json",
|
|
14
14
|
"clean": "rm -rf dist types",
|
|
15
15
|
"np": "np",
|
|
16
|
-
"release": "run-s clean build np"
|
|
16
|
+
"release": "run-s clean build np",
|
|
17
|
+
"eslintLog": "eslint . > eslint.log"
|
|
17
18
|
},
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var e=require("node:fs/promises"),t=require("pull-md-img"),r=require("ora"),o=require("cli-progress"),i=require("log4js"),s=require("axios"),n=require("rand-user-agent");var a,c,l=(i.configure({appenders:{cheese:{type:"console",layout:{type:"pattern",pattern:"%[%c [%p]:%] %m%n"}}},categories:{default:{appenders:["cheese"],level:"trace"}}}),i.getLogger("yuque-dl"));class u{constructor(e,t){this.bookPath="",this.progressFilePath="",this.progressInfo=[],this.curr=0,this.total=0,this.isDownloadInterrupted=!1,this.bar=null,this.completePromise=null,this.bookPath=e,this.progressFilePath=`${e}/progress.json`,this.total=t}async init(){this.progressInfo=await this.getProgress(),this.curr=this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&(this.isDownloadInterrupted=!0,l.info("根据上次数据继续断点下载")),this.bar=new o.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},o.Presets.legacy),this.bar.start(this.total,this.curr))}async getProgress(){let t=[];try{const r=await e.readFile(this.progressFilePath,{encoding:"utf8"});t=JSON.parse(r)}catch(r){r&&"ENOENT"===r.code&&await e.writeFile(this.progressFilePath,JSON.stringify(t),{encoding:"utf8"})}return t}async updateProgress(t,r){this.curr=this.curr+1,r&&(this.progressInfo.push(t),await e.writeFile(this.progressFilePath,JSON.stringify(this.progressInfo),{encoding:"utf8"})),this.bar&&(this.bar.update(this.curr),this.curr>=this.total&&(this.bar.stop(),console.log("")))}pause(){this.bar&&this.bar.stop()}continue(){this.clearLine(2),this.bar?.start(this.total,this.curr)}clearLine(e){if(!(e<=0)){process.stderr.cursorTo(0);for(let t=0;t<e;t++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}class d{constructor(e){this.summaryInfo=e}async genFile(){const{bookName:t,bookDesc:r,bookPath:o,uuidMap:i}=this.summaryInfo;let s=`# ${t}\n\n`;r&&(s+=`> ${r}\n\n`);let n=s;const a=[];i.forEach((e=>{const t=e.toc,r=t.parent_uuid,o=this.findTree(a,r),i={text:t.title.replace(/[\\\/:\*\?"<>\|\n\r]/g,"_").replace(/\s/,""),id:t.uuid,level:1,type:""},s=t.type.toLocaleLowerCase();"title"===s||""!==t.child_uuid?(i.type="title","boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),i.level=o.level+1,o.children.push(i)):(i.level=1,a.push(i))):(i.type="link",i.link="link"===s?e.toc.url:e.path,"boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),i.level=o.level+1,o.children.push(i)):(i.level=1,a.push(i)))})),n+=this.genSummaryContent(a,"");try{await e.writeFile(`${o}/SUMMARY.md`,n)}catch(e){l.error("Generate Summary Error")}}genSummaryContent(e,t){for(let r=0;r<e.length;r++){const o=e[r];if("title"===o.type)t+=`\n${"".padStart(o.level+1,"#")} ${o.text}\n\n`;else if("link"===o.type){const e=o.link?o.link.replace(/\s/g,"%20"):o.link;t+=`- [${o.text}](${e})\n`}Array.isArray(o.children)&&(t+=this.genSummaryContent(o.children,""))}return t}findIdItem(e,t){if(e.id===t)return e;if(e.children){const r=this.findTree(e.children,t);if(r)return r}return!1}findTree(e,t){if(!t)return!1;for(let r=0;r<e.length;r++){const o=this.findIdItem(e[r],t);if(o)return o}return!1}}!function(e){e.TITLE="title",e.LINK="link",e.DOC="doc"}(a||(a={})),function(e){e.BOARD="board",e.TABLE="table",e.SHEET="sheet",e.DOC="doc"}(c||(c={}));const h=new Map([[c.BOARD,"画板类型"],[c.TABLE,"数据表类型"],[c.SHEET,"表格类型"],[c.DOC,"文档类型"]]);function p({browser:e="chrome",os:t="mac os",device:r="desktop"}){r=r.toLowerCase(),e=e.toLowerCase(),t=t.toLowerCase();let o=n(r,e,t);if("chrome"===e)for(;o.includes("Chrome-Lighthouse")||o.includes("Gener8")||o.includes("HeadlessChrome")||o.includes("SMTBot");)o=n(r,e,t);if("safari"===e)for(;o.includes("Applebot");)o=n(r,e,t);return o}function g(e){const t={"user-agent":p({browser:"chrome",device:"desktop"})};return e&&(t.cookie=`_yuque_session=${e}`),t}const f=e=>{const{articleUrl:t,bookId:r,token:o}=e;let i=`https://www.yuque.com/api/docs/${t}`;const n={book_id:String(r),merge_dynamic_data:String(!1),mode:"markdown"},a=new URLSearchParams(n).toString();return i=`${i}?${a}`,s.get(i,{headers:g(o)}).then((({data:e,status:t})=>({apiUrl:i,httpStatus:t,response:e})))};async function w(o,i,s){const{bookId:n,itemUrl:a,savePath:l,saveFilePath:u,uuid:d,articleUrl:p,articleTitle:g,ignoreImg:w}=o,{httpStatus:m,apiUrl:b,response:$}=await f({articleUrl:a,bookId:n,token:s}),k=$?.data?.type?.toLocaleLowerCase();if([c.BOARD,c.SHEET,c.TABLE].includes(k)){const e=h.get(k);throw new Error(`download article Error: 暂不支持“${e}”的文档`)}if("string"!=typeof $?.data?.sourcecode)throw new Error(`download article Error: ${b}, http status ${m}`);let y=$.data.sourcecode;if(!w){i.pause(),console.log("");const e=r({text:`下载 "${g}" 的图片中...`});e.start();try{y=await t.run(y,{dist:l,imgDir:`./img/${d}`,isIgnoreConsole:!0})}catch(e){let t=`download article image Error: ${e.message}`;throw e.error&&e.url&&(t=`download article image Error ${e.url}: ${e.error?.message}`),new Error(t)}finally{e.stop(),i.continue()}}y=y.replace(/<br(\s?)\/>/gm,"\n"),g&&(y=`# ${g}\n\x3c!--page header--\x3e\n\n${y}\n\n`),p&&(y+=`\x3c!--page footer--\x3e\n- 原文: <${p}>`);try{return await e.writeFile(u,y),!0}catch(e){throw new Error(`download article Error ${p}: ${e.message}`)}}function m(e){if(!e)return"";return e.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"")}exports.downloadArticle=w,exports.logger=l,exports.main=async function(t,r){const{bookId:o,tocList:i,bookName:n,bookDesc:c,bookSlug:h}=await((e,t)=>{const r=/decodeURIComponent\("(.+)"\)\);/m;return s.get(e,{headers:g(t)}).then((({data:e="",status:t})=>200===t?e:"")).then((e=>{const t=r.exec(e)??"";if(!t[1])return{};const o=JSON.parse(decodeURIComponent(t[1]));return o.book?{bookId:o.book.id,bookSlug:o.book.slug,tocList:o.book.toc||[],bookName:o.book.name||"",bookDesc:o.book.description||""}:{}}))})(t,r.token);if(!o)throw new Error("No found book id");if(!i||0===i.length)throw new Error("No found toc list");const p=`${r.distDir}/${n?m(n):o}`;await e.mkdir(p,{recursive:!0});const f=i.length,b=new u(p,f);if(await b.init(),b.curr===f)return b.bar&&b.bar.stop(),void l.info(`√ 已完成: ${process.cwd()}/${p}`);const $=new Map;b.isDownloadInterrupted&&b.progressInfo.forEach((e=>{$.set(e.toc.uuid,e)}));const k=t.replace(new RegExp(`(.*?/${h}).*`),"$1");await async function(t){const{articleUrlPrefix:r,total:o,uuidMap:i,tocList:s,bookPath:n,bookId:c,progressBar:u,options:d}=t;let h=0,p=0,g=0,f=[],b=[];for(let t=0;t<o;t++){const o=s[t];if("string"!=typeof o.type)continue;if(i.get(o.uuid))continue;const l=o.type.toLocaleLowerCase();if(l===a.TITLE||""!==o.child_uuid||l===a.LINK){let t=o,r=[],s=[];for(;t;)r.unshift(m(t.title)),s.unshift(t.uuid),t=i.get(t.parent_uuid)?i.get(t.parent_uuid).toc:void 0;const c={path:r.join("/"),pathTitleList:r,pathIdList:s,toc:o};l===a.LINK?(g+=1,b.push(c)):await e.mkdir(`${n}/${r.join("/")}`,{recursive:!0}),i.set(o.uuid,c),await u.updateProgress(c,l!==a.LINK)}else if(o.url){p+=1;let e={path:"",pathTitleList:[],pathIdList:[]};i.get(o.parent_uuid)&&(e=i.get(o.parent_uuid));const t=m(o.title),s=[...e.pathTitleList,`${t}.md`],a=[...e.pathIdList,o.uuid],l={path:s.join("/"),pathTitleList:s,pathIdList:a,toc:o};let g=!0;const b=`${r}/${o.url}`;try{await w({bookId:c,itemUrl:o.url,savePath:`${n}/${e.path}`,saveFilePath:`${n}/${l.path}`,uuid:o.uuid,articleUrl:b,articleTitle:o.title,ignoreImg:d.ignoreImg},u,d.token)}catch(e){g=!1,h+=1,f.push({articleUrl:b,errItem:l,errMsg:e.message,err:e})}i.set(o.uuid,l),await u.updateProgress(l,g)}}if(g>0){l.warn("该知识库存在以下外链文章");for(const e of b)l.warn(`———— ✕ ${e.path} ${e.toc.url}`)}if(h>0){l.error(`本次执行总数${p}篇,✕ 失败${h}篇`);for(const e of f)l.error(`${e.errItem.path} ———— ${e.articleUrl}`),l.error(`———— ✕ ${e.errMsg}`);l.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}}({articleUrlPrefix:k,total:f,uuidMap:$,tocList:i,bookPath:p,bookId:o,progressBar:b,options:r});const y=new d({bookPath:p,bookName:n,bookDesc:c,uuidMap:$});await y.genFile();const I=process.cwd();l.info(`√ 生成目录 ${I}/${p}/SUMMARY.md`),b.curr===f&&l.info(`√ 已完成: ${I}/${p}`),process.exit(0)};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import t,{writeFile as e,mkdir as r}from"node:fs/promises";import o from"pull-md-img";import i from"ora";import s from"cli-progress";import n from"log4js";import a from"axios";import c from"rand-user-agent";var l,u,h=(n.configure({appenders:{cheese:{type:"console",layout:{type:"pattern",pattern:"%[%c [%p]:%] %m%n"}}},categories:{default:{appenders:["cheese"],level:"trace"}}}),n.getLogger("yuque-dl"));class d{constructor(t,e){this.bookPath="",this.progressFilePath="",this.progressInfo=[],this.curr=0,this.total=0,this.isDownloadInterrupted=!1,this.bar=null,this.completePromise=null,this.bookPath=t,this.progressFilePath=`${t}/progress.json`,this.total=e}async init(){this.progressInfo=await this.getProgress(),this.curr=this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&(this.isDownloadInterrupted=!0,h.info("根据上次数据继续断点下载")),this.bar=new s.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},s.Presets.legacy),this.bar.start(this.total,this.curr))}async getProgress(){let e=[];try{const r=await t.readFile(this.progressFilePath,{encoding:"utf8"});e=JSON.parse(r)}catch(r){r&&"ENOENT"===r.code&&await t.writeFile(this.progressFilePath,JSON.stringify(e),{encoding:"utf8"})}return e}async updateProgress(e,r){this.curr=this.curr+1,r&&(this.progressInfo.push(e),await t.writeFile(this.progressFilePath,JSON.stringify(this.progressInfo),{encoding:"utf8"})),this.bar&&(this.bar.update(this.curr),this.curr>=this.total&&(this.bar.stop(),console.log("")))}pause(){this.bar&&this.bar.stop()}continue(){this.clearLine(2),this.bar?.start(this.total,this.curr)}clearLine(t){if(!(t<=0)){process.stderr.cursorTo(0);for(let e=0;e<t;e++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}class p{constructor(t){this.summaryInfo=t}async genFile(){const{bookName:e,bookDesc:r,bookPath:o,uuidMap:i}=this.summaryInfo;let s=`# ${e}\n\n`;r&&(s+=`> ${r}\n\n`);let n=s;const a=[];i.forEach((t=>{const e=t.toc,r=e.parent_uuid,o=this.findTree(a,r),i={text:e.title.replace(/[\\\/:\*\?"<>\|\n\r]/g,"_").replace(/\s/,""),id:e.uuid,level:1,type:""},s=e.type.toLocaleLowerCase();"title"===s||""!==e.child_uuid?(i.type="title","boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),i.level=o.level+1,o.children.push(i)):(i.level=1,a.push(i))):(i.type="link",i.link="link"===s?t.toc.url:t.path,"boolean"!=typeof o?(Array.isArray(o.children)||(o.children=[]),i.level=o.level+1,o.children.push(i)):(i.level=1,a.push(i)))})),n+=this.genSummaryContent(a,"");try{await t.writeFile(`${o}/SUMMARY.md`,n)}catch(t){h.error("Generate Summary Error")}}genSummaryContent(t,e){for(let r=0;r<t.length;r++){const o=t[r];if("title"===o.type)e+=`\n${"".padStart(o.level+1,"#")} ${o.text}\n\n`;else if("link"===o.type){const t=o.link?o.link.replace(/\s/g,"%20"):o.link;e+=`- [${o.text}](${t})\n`}Array.isArray(o.children)&&(e+=this.genSummaryContent(o.children,""))}return e}findIdItem(t,e){if(t.id===e)return t;if(t.children){const r=this.findTree(t.children,e);if(r)return r}return!1}findTree(t,e){if(!e)return!1;for(let r=0;r<t.length;r++){const o=this.findIdItem(t[r],e);if(o)return o}return!1}}!function(t){t.TITLE="title",t.LINK="link",t.DOC="doc"}(l||(l={})),function(t){t.BOARD="board",t.TABLE="table",t.SHEET="sheet",t.DOC="doc"}(u||(u={}));const g=new Map([[u.BOARD,"画板类型"],[u.TABLE,"数据表类型"],[u.SHEET,"表格类型"],[u.DOC,"文档类型"]]);function f({browser:t="chrome",os:e="mac os",device:r="desktop"}){r=r.toLowerCase(),t=t.toLowerCase(),e=e.toLowerCase();let o=c(r,t,e);if("chrome"===t)for(;o.includes("Chrome-Lighthouse")||o.includes("Gener8")||o.includes("HeadlessChrome")||o.includes("SMTBot");)o=c(r,t,e);if("safari"===t)for(;o.includes("Applebot");)o=c(r,t,e);return o}function m(t){const e={"user-agent":f({browser:"chrome",device:"desktop"})};return t&&(e.cookie=`_yuque_session=${t}`),e}const w=t=>{const{articleUrl:e,bookId:r,token:o}=t;let i=`https://www.yuque.com/api/docs/${e}`;const s={book_id:String(r),merge_dynamic_data:String(!1),mode:"markdown"},n=new URLSearchParams(s).toString();return i=`${i}?${n}`,a.get(i,{headers:m(o)}).then((({data:t,status:e})=>({apiUrl:i,httpStatus:e,response:t})))};async function b(t,r,s){const{bookId:n,itemUrl:a,savePath:c,saveFilePath:l,uuid:h,articleUrl:d,articleTitle:p,ignoreImg:f}=t,{httpStatus:m,apiUrl:b,response:$}=await w({articleUrl:a,bookId:n,token:s}),k=$?.data?.type?.toLocaleLowerCase();if([u.BOARD,u.SHEET,u.TABLE].includes(k)){const t=g.get(k);throw new Error(`download article Error: 暂不支持“${t}”的文档`)}if("string"!=typeof $?.data?.sourcecode)throw new Error(`download article Error: ${b}, http status ${m}`);let y=$.data.sourcecode;if(!f){r.pause(),console.log("");const t=i({text:`下载 "${p}" 的图片中...`});t.start();try{y=await o.run(y,{dist:c,imgDir:`./img/${h}`,isIgnoreConsole:!0})}catch(t){let e=`download article image Error: ${t.message}`;throw t.error&&t.url&&(e=`download article image Error ${t.url}: ${t.error?.message}`),new Error(e)}finally{t.stop(),r.continue()}}y=y.replace(/<br(\s?)\/>/gm,"\n"),p&&(y=`# ${p}\n\x3c!--page header--\x3e\n\n${y}\n\n`),d&&(y+=`\x3c!--page footer--\x3e\n- 原文: <${d}>`);try{return await e(l,y),!0}catch(t){throw new Error(`download article Error ${d}: ${t.message}`)}}function $(t){if(!t)return"";return t.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"")}async function k(t,e){const{bookId:o,tocList:i,bookName:s,bookDesc:n,bookSlug:c}=await((t,e)=>{const r=/decodeURIComponent\("(.+)"\)\);/m;return a.get(t,{headers:m(e)}).then((({data:t="",status:e})=>200===e?t:"")).then((t=>{const e=r.exec(t)??"";if(!e[1])return{};const o=JSON.parse(decodeURIComponent(e[1]));return o.book?{bookId:o.book.id,bookSlug:o.book.slug,tocList:o.book.toc||[],bookName:o.book.name||"",bookDesc:o.book.description||""}:{}}))})(t,e.token);if(!o)throw new Error("No found book id");if(!i||0===i.length)throw new Error("No found toc list");const u=`${e.distDir}/${s?$(s):o}`;await r(u,{recursive:!0});const g=i.length,f=new d(u,g);if(await f.init(),f.curr===g)return f.bar&&f.bar.stop(),void h.info(`√ 已完成: ${process.cwd()}/${u}`);const w=new Map;f.isDownloadInterrupted&&f.progressInfo.forEach((t=>{w.set(t.toc.uuid,t)}));const k=t.replace(new RegExp(`(.*?/${c}).*`),"$1");await async function(t){const{articleUrlPrefix:e,total:o,uuidMap:i,tocList:s,bookPath:n,bookId:a,progressBar:c,options:u}=t;let d=0,p=0,g=0,f=[],m=[];for(let t=0;t<o;t++){const o=s[t];if("string"!=typeof o.type)continue;if(i.get(o.uuid))continue;const h=o.type.toLocaleLowerCase();if(h===l.TITLE||""!==o.child_uuid||h===l.LINK){let t=o,e=[],s=[];for(;t;)e.unshift($(t.title)),s.unshift(t.uuid),t=i.get(t.parent_uuid)?i.get(t.parent_uuid).toc:void 0;const a={path:e.join("/"),pathTitleList:e,pathIdList:s,toc:o};h===l.LINK?(g+=1,m.push(a)):await r(`${n}/${e.join("/")}`,{recursive:!0}),i.set(o.uuid,a),await c.updateProgress(a,h!==l.LINK)}else if(o.url){p+=1;let t={path:"",pathTitleList:[],pathIdList:[]};i.get(o.parent_uuid)&&(t=i.get(o.parent_uuid));const r=$(o.title),s=[...t.pathTitleList,`${r}.md`],l=[...t.pathIdList,o.uuid],h={path:s.join("/"),pathTitleList:s,pathIdList:l,toc:o};let g=!0;const m=`${e}/${o.url}`;try{await b({bookId:a,itemUrl:o.url,savePath:`${n}/${t.path}`,saveFilePath:`${n}/${h.path}`,uuid:o.uuid,articleUrl:m,articleTitle:o.title,ignoreImg:u.ignoreImg},c,u.token)}catch(t){g=!1,d+=1,f.push({articleUrl:m,errItem:h,errMsg:t.message,err:t})}i.set(o.uuid,h),await c.updateProgress(h,g)}}if(g>0){h.warn("该知识库存在以下外链文章");for(const t of m)h.warn(`———— ✕ ${t.path} ${t.toc.url}`)}if(d>0){h.error(`本次执行总数${p}篇,✕ 失败${d}篇`);for(const t of f)h.error(`${t.errItem.path} ———— ${t.articleUrl}`),h.error(`———— ✕ ${t.errMsg}`);h.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}}({articleUrlPrefix:k,total:g,uuidMap:w,tocList:i,bookPath:u,bookId:o,progressBar:f,options:e});const y=new p({bookPath:u,bookName:s,bookDesc:n,uuidMap:w});await y.genFile();const I=process.cwd();h.info(`√ 生成目录 ${I}/${u}/SUMMARY.md`),f.curr===g&&h.info(`√ 已完成: ${I}/${u}`),process.exit(0)}export{b as d,h as l,k as m};
|