yuque-dl 1.0.78 → 1.0.80
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/dist/es/cli.js +1 -1
- package/dist/es/index-CjEfavqS.js +1 -0
- package/dist/es/index.js +1 -1
- package/package.json +5 -4
- package/types/types/Attachments.d.ts +17 -0
- package/types/types/Video.d.ts +40 -0
- package/types/types/index.d.ts +6 -1
- package/dist/es/index-ConFUJXT.js +0 -1
package/dist/es/cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,l as o,m as n}from"./index-
|
|
1
|
+
import{_ as e,l as o,m as n}from"./index-CjEfavqS.js";import{existsSync as t,readFileSync as i}from"node:fs";import{cac as r}from"cac";import s from"semver";import"rand-user-agent";import{mkdir as d,copyFile as c,readFile as l,writeFile as m,access as p,readdir as a,stat as u}from"node:fs/promises";import"cli-progress";import{resolve as f,join as h,sep as v,dirname as y}from"node:path";import{fileURLToPath as g}from"node:url";import{createServer as x}from"vitepress";import"log4js";import"node:process";import"axios";import"ora";import"pull-md-img";import"markdown-toc";import"pako";import"node:crypto";import"node:stream";import"node:util";import"mdast-util-from-markdown";import"mdast-util-to-markdown";let k;function w(o,n){return e(this,void 0,void 0,(function*(){const i=f(o);if(!(yield $(i)))throw new Error("server root not found");const r=h(i,"/.vitepress");t(r)&&!n.force||(yield function(o){return e(this,void 0,void 0,(function*(){const n=o.split(v).filter(Boolean).at(-1)||"yuque-dl",t=h(o,"/.vitepress");yield d(t,{recursive:!0});const i=y(g(import.meta.url)),r=h(i,"../../server-lib/bundle.js"),s=h(t,"bundle.mjs");yield c(r,s);const p=h(t,"config.mjs"),x=yield function(o){return e(this,void 0,void 0,(function*(){const e=[],n=[".vitepress","img","index.md","progress.json","attachments"];let t=yield a(o);t=t.filter((e=>!n.includes(e)));for(const n of t){const t=h(o,n);if((yield u(t)).isDirectory()){const i=yield $(h(t,"index.md")),r={text:n,collapsed:!0,items:yield b(o,n)};i&&(r.link=`/${n}/`),e.push(r)}else e.push({text:n.slice(0,n.lastIndexOf(".")),link:`/${n}`})}return e}))}(o);M((yield l(f(o,"index.md"),"utf8")).split("\n"),x),E(x);const k=`\n import {fixHtmlTags} from './bundle.mjs'\n export default {\n title: "${n}",\n themeConfig: {\n search: {\n provider: 'local'\n },\n sidebar: ${JSON.stringify(x)}\n },\n vite: {\n optimizeDeps: {\n include: []\n }\n },\n markdown: {\n html: true,\n breaks: true,\n config(md) {\n // 包装原始 render 方法,捕获解析异常\n const originalRender = md.render.bind(md);\n md.render = (src, env) => {\n try {\n let newMd = fixHtmlTags(originalRender(src, env))\n newMd = newMd.replace('<html><head></head><body>', '')\n newMd = newMd.replace('</body></html>', '')\n return newMd\n } catch (error) {\n console.error("Markdown/HTML parsing error:", error);\n return src\n }\n }\n }\n }\n }\n `;yield m(p,k)}))}(i));const s=()=>e(this,void 0,void 0,(function*(){const t=yield x(o,{host:n.host,port:n.port},(()=>e(this,void 0,void 0,(function*(){return k||(k=(()=>e(this,void 0,void 0,(function*(){yield t.close(),yield s()})))().finally((()=>{k=void 0}))),k}))));yield t.listen(),t.printUrls()}));yield s().catch((e=>{console.error(e),process.exit(1)}))}))}function $(o){return e(this,void 0,void 0,(function*(){try{return yield p(o),!0}catch(e){if("ENOENT"===e.code)return!1;throw e}}))}function M(e,o){o.map((o=>{"items"in o&&M(e,o.items);const n=e.findIndex((e=>e.includes(`[${o.text}]`)||e.includes(`# ${o.text}`)));o.index=n}))}function E(e){e.length<=1||(e.forEach((e=>{"items"in e&&E(e.items)})),e.sort(((e,o)=>e.index&&o.index?e.index>o.index?1:-1:0)))}function b(o,...n){return e(this,void 0,void 0,(function*(){const e=yield a(h(o,...n)),t=[];for(const i of e){const e=h(o,...n,i);if((yield u(e)).isDirectory()){const r=yield b(h(o),...n,i);if(r.length>0){const o={text:i,items:r,collapsed:false};(yield $(h(e,"index.md")))&&(o.link="/"+[...n,i].map(decodeURIComponent).join("/")+"/"),t.push(o)}}else{if("index.md"===i||/^-.*\.(md|MD)$/.test(i)||!i.endsWith(".md"))continue;const e=i.replace(/\.md$/,""),o={text:e,link:"/"+[...n.map(decodeURIComponent),`${encodeURI(e)}.html`].join("/")};t.push(o)}}return t}))}const N=r("yuque-dl"),{version:j,engines:_}=JSON.parse(i(new URL("../../package.json",import.meta.url)).toString());!function(){const e=_.node;s.satisfies(process.version,e)||(o.error(`✕ nodejs 版本需 ${e}, 当前版本为 ${process.version}`),process.exit(1))}(),N.command("<url>","语雀知识库url").option("-d, --distDir <dir>","下载的目录{CUSTOM_NEW_LINE(eg: -d download)}",{default:"download"}).option("-i, --ignoreImg","忽略图片不下载",{default:!1}).option("--ignoreAttachments [fileExtension]","忽略附件, 可选带上忽略的附件文件后缀(多种后缀逗号分割){CUSTOM_NEW_LINE(eg: --ignoreAttachments mp4,pdf // 忽略后缀名mp4,pdf的附件)}{CUSTOM_NEW_LINE(eg: --ignoreAttachments // 忽略所有附件)}",{default:!1}).option("-k, --key <key>",'语雀的cookie key, 默认是 "_yuque_session", 在某些企业版本中 key 不一样').option("-t, --token <token>","语雀的cookie key 对应的值").option("--toc","是否输出文档toc目录",{default:!1}).option("--incremental","开启增量下载[初次下载加不加该参数没区别]",{default:!1}).option("--convertMarkdownVideoLinks","转化markdown视频链接为video标签",{default:!1}).option("--hideFooter","是否禁用页脚显示[更新时间、原文地址...]",{default:!1}).action(((t,i)=>e(void 0,void 0,void 0,(function*(){try{yield n(t,i),process.exit(0)}catch(e){o.error(e.message||"unknown exception"),process.exit(1)}})))),N.command("server <serverPath>","启动web服务").option("-p, --port <port>"," --port 1234",{default:5173}).option("--host [host]"," --host 0.0.0.0 或 --host",{default:"localhost"}).option("--force","强制重新生成.vitepress",{default:!1}).action(((n,t)=>e(void 0,void 0,void 0,(function*(){try{yield w(n,t)}catch(e){o.error(e.message||"unknown exception"),process.exit(1)}})))),N.help((e=>{var o;const n=e.find((e=>"Options"===e.title));if(n){let e=(null==n?void 0:n.body)||"";e=e.replace(/^(\s*-h, --help\s*)(.*)$/gm,((e,o)=>`${o}显示帮助信息`)),e=e.replace(/^(\s*-v, --version\s*)(.*)$/gm,((e,o)=>`${o}显示当前版本`)),e=e.replace(/\(default:/gm,(()=>"(默认值:"));const t=(null===(o=e.match(/^(\s*-h, --help\s*)/gm))||void 0===o?void 0:o[0].length)||0;e=e.replace(/\{CUSTOM_NEW_LINE\((.*?)\)\}/g,((e,o)=>`\n${"".padStart(t," ")} └─ ${o}`)),n.body=e}})),N.version(j);try{N.parse()}catch(e){o.error(e.message||"unknown exception"),process.exit(1)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e,{writeFile as t,mkdir as o}from"node:fs/promises";import n from"node:path";import r from"rand-user-agent";import i from"log4js";import s from"cli-progress";import{env as a,stdout as l}from"node:process";import c from"axios";import d from"ora";import u from"pull-md-img";import h from"markdown-toc";import f from"pako";import p from"node:crypto";import{createWriteStream as m,mkdirSync as v}from"node:fs";import*as g from"node:stream";import{promisify as y}from"node:util";import{fromMarkdown as k}from"mdast-util-from-markdown";import{toMarkdown as w}from"mdast-util-to-markdown";function $(e,t,o,n){return new(o||(o=Promise))((function(r,i){function s(e){try{l(n.next(e))}catch(e){i(e)}}function a(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(s,a)}l((n=n.apply(e,t||[])).next())}))}var I,b;"function"==typeof SuppressedError&&SuppressedError,function(e){e.TITLE="title",e.LINK="link",e.DOC="doc"}(I||(I={})),function(e){e.BOARD="board",e.TABLE="table",e.SHEET="sheet",e.DOC="doc"}(b||(b={}));const D=new Map([[b.BOARD,"画板类型"],[b.TABLE,"数据表类型"],[b.SHEET,"表格类型"],[b.DOC,"文档类型"]]),E="_yuque_session",N="https://www.yuque.com",P="UXO91eVnUveQn8suOJaYMvBcWs9KptS8N5HoP8ezSeU4vqApZpy1CkPaTpkpQEx2W2mlhxL8zwS8UePwBgksUM0CTtAODbTTTDFD",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,o=!1){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,this.incremental=o}init(){return $(this,void 0,void 0,(function*(){this.progressInfo=yield this.getProgress(),this.curr=this.incremental?0:this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&!this.incremental&&(this.isDownloadInterrupted=!0,L.info("根据上次数据继续断点下载")),this.bar=new s.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},s.Presets.legacy),this.bar.start(this.total,this.curr))}))}getProgress(){return $(this,void 0,void 0,(function*(){let t=[];try{const o=yield e.readFile(this.progressFilePath,{encoding:"utf8"});t=JSON.parse(o)}catch(o){o&&"ENOENT"===o.code&&(yield e.writeFile(this.progressFilePath,JSON.stringify(t),{encoding:"utf8"}))}return t}))}updateProgress(t,o){return $(this,void 0,void 0,(function*(){if(this.curr!==this.total){if(this.curr=this.curr+1,o){const o=t.toc.uuid,n=this.progressInfo.find((e=>e.toc.uuid===o));n?Object.assign(n,t):this.progressInfo.push(t),yield 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(){var e;this.clearLine(2),null===(e=this.bar)||void 0===e||e.start(this.total,this.curr)}clearLine(e){var t;if(!(e<=0)&&"function"==typeof(null===(t=null===process||void 0===process?void 0:process.stderr)||void 0===t?void 0:t.cursorTo)){process.stderr.cursorTo(0);for(let t=0;t<e;t++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}function T({browser:e="chrome",os:t="mac os",device:o="desktop"}){o=o.toLowerCase(),e=e.toLowerCase(),t=t.toLowerCase();let n=r(o,e,t);if("chrome"===e)for(;n.includes("Chrome-Lighthouse")||n.includes("Gener8")||n.includes("HeadlessChrome")||n.includes("SMTBot");)n=r(o,e,t);if("safari"===e)for(;n.includes("Applebot");)n=r(o,e,t);return n}function S(e){return e.toString().padStart(2,"0")}function O(e){const t=new Date(e);if(isNaN(t.getTime()))return"";const o=t.getFullYear(),n=t.getMonth()+1,r=t.getDate(),i=t.getHours(),s=t.getMinutes(),a=t.getSeconds();return`${o}-${S(n)}-${S(r)} ${S(i)}:${S(s)}:${S(a)}`}function x(e){return e instanceof Date&&!isNaN(e.getTime())}class A{constructor(e){this.summaryInfo=e}genFile(){return $(this,void 0,void 0,(function*(){const{bookName:t,bookDesc:o,bookPath:n,uuidMap:r}=this.summaryInfo;let i=`# ${t}\n\n`;o&&(i+=`> ${o}\n\n`);let s=i;const a=[];r.forEach((e=>{const t=e.toc,o=t.parent_uuid,n=this.findTree(a,o),r={text:t.title.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/,""),id:t.uuid,level:1,type:"link"},i=t.type.toLocaleLowerCase();i===I.TITLE||""!==t.child_uuid?(r.type="title","boolean"!=typeof n?(Array.isArray(n.children)||(n.children=[]),r.level=n.level+1,n.children.push(r)):(r.level=1,a.push(r)),i===I.DOC&&(r.link=e.path)):(r.type="link",r.link=i===I.LINK?e.toc.url:e.path,"boolean"!=typeof n?(Array.isArray(n.children)||(n.children=[]),r.level=n.level+1,n.children.push(r)):(r.level=1,a.push(r)))}));s+=this.genSummaryContent(a,"");try{yield e.writeFile(`${n}/index.md`,s)}catch(e){L.error("Generate Summary Error")}return s}))}genSummaryContent(e,t){for(const o of e){if(o.type===I.TITLE)if(o.link){const e=o.link?o.link.replace(/\s/g,"%20"):o.link;t+=`\n${"".padStart(o.level+1,"#")} [${o.text}](${e})\n\n`}else t+=`\n${"".padStart(o.level+1,"#")} ${o.text}\n\n`;else if(o.type===I.LINK){const e=o.link?o.link.replace(/\s/g,"%20"):o.link;t+=`${1===o.level?"\n##":"-"} [${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 o=this.findTree(e.children,t);if(o)return o}return!1}findTree(e,t){if(!t)return!1;for(const o of e){const e=this.findIdItem(o,t);if(e)return e}return!1}}function C(e){const{key:t=E,token:o}=e,n={"user-agent":T({browser:"chrome",device:"desktop"})};return o&&(n.cookie=`${t}=${o};`),n}function F(e){const t={headers:C(e),beforeRedirect:t=>{t.headers=Object.assign(Object.assign({},(null==t?void 0:t.headers)||{}),C(e))}};return"test"===a.NODE_ENV&&(t.proxy=!1),t}const _=(e,t=!0)=>{const{articleUrl:o,bookId:n,token:r,key:i,host:s=N}=e;let a=`${s}/api/docs/${o}`;const l={book_id:String(n),merge_dynamic_data:String(!1)};t&&(l.mode="markdown");const d=new URLSearchParams(l).toString();return a=`${a}?${d}`,c.get(a,F({token:r,key:i})).then((({data:e,status:t})=>({apiUrl:a,httpStatus:t,response:e})))};function j(e){if(!e)return"";return e.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"").replace(/[\ud800-\udbff][\udc00-\udfff]/g,"")}const R=e=>{if(!e)return"";const t=f.inflate(e,{to:"string"}),o=JSON.parse(t);let n="";return o.forEach((e=>{const t=`## ${e.name}\n`,o=function(e){var t,o,n;let r=Object.keys(e);r=r.filter((t=>Object.keys(e[t]).some((o=>{var n,r;return null===(r=null===(n=null==e?void 0:e[t])||void 0===n?void 0:n[o])||void 0===r?void 0:r.v}))));let i=[];r.forEach((t=>{const o=e[t];o&&(i=i.concat(Object.keys(o)))}));const s=Math.max(...r.map((e=>Number(e)))),a=Math.max(...i.map((e=>Number(e))));if(s<0||a<0)return"";let l="";const c="ABCDEFGHIJKLMNOPQRSTUVWXYZ";let d=Array(a+1).fill(" ").map(((e,t)=>{const o=t%c.length;return c[o]})).join(" | ");d=`| |${d}|`;let u=Array(a+2).fill("---").join(" |");u=`|${u}|`,l=`${d}\n${u}\n`;for(let r=0;r<s+1;r++){const i=[];for(let s=0;s<a+1;s++){const a=(null===(o=null===(t=null==e?void 0:e[r])||void 0===t?void 0:t[s])||void 0===o?void 0:o.v)||null;a&&"string"==typeof a?i.push(a):a&&"object"==typeof a?"image"===(null==a?void 0:a.class)&&(null==a?void 0:a.src)?i.push(``):"checkbox"===(null==a?void 0:a.class)?i.push((null==a?void 0:a.value)?"[x] ":"[ ] "):"link"===(null==a?void 0:a.class)?i.push(`[${null==a?void 0:a.text}](${null==a?void 0:a.url})`):"select"===(null==a?void 0:a.class)&&i.push(null===(n=null==a?void 0:a.value)||void 0===n?void 0:n.join(",")):i.push(null)}l=`${l}${`| ${r+1} | ${i.join(" | ")}|`}\n`}return l}(e.data);n=`${n}\n${t}\n${o}`})),n};function M(e,t=[]){return function(e,t){try{const{host:o,pathname:n}=new URL(e);return!t.includes(o)&&Boolean(n)}catch(e){return!1}}(e,t)?`https://www.yuque.com/api/filetransfer/images?url=${encodeURIComponent(e)}&sign=${function(e){const t=p.createHash("sha256");return t.update(`${P}${e}`),t.digest("hex")}(e)}`:e}const B=y(g.finished);function J(e){return $(this,void 0,void 0,(function*(){const{fileUrl:t,savePath:o,token:n,key:r,fileName:i}=e;return c.get(t,Object.assign(Object.assign({},F({token:n,key:r})),{responseType:"stream"})).then((e=>$(this,void 0,void 0,(function*(){var n,r,s;if(null===(r=null===(n=e.request)||void 0===n?void 0:n.path)||void 0===r?void 0:r.startsWith("/login"))throw new Error(`"${i}" need token`);if(200===e.status){const n=m(o);return null===(s=e.data)||void 0===s||s.pipe(n),B(n).then((()=>({fileUrl:t,savePath:o})))}throw new Error(`response status ${e.status}`)}))))}))}const V=/\[(.*?)\]\((.*?)\)/g,q=/\[(.*?)\]\((.*?\.yuque\.com\/attachments.*?)\)/;function H(e){return $(this,void 0,void 0,(function*(){const{mdData:t,savePath:o,attachmentsDir:r,articleTitle:i,token:s,key:c,ignoreAttachments:u}=e,h=(t.match(V)||[]).filter((e=>q.test(e)));if(0===h.length)return{mdData:t};const f=n.resolve(o,r);let p=h.map((e=>function(e,t){const[,o,r]=q.exec(e)||[];if(!r)return!1;const i=o||r.split("/").at(-1);if(!i)return!1;const s=n.join(t,i);return{fileName:i,url:r,rawMd:e,currentFilePath:s}}(e,f))).filter((e=>!1!==e));if("string"==typeof u){const e=u.split(",");p=p.filter((t=>{const o=t.url.lastIndexOf(".");if(-1===o)return!0;const n=t.url.slice(o+1);return!e.find((e=>e===n))}))}if(0===p.length)return{mdData:t};const m=d({text:`下载 "${i}" 的附件中...`,stream:l});"test"!==a.NODE_ENV&&m.start(),v(f,{recursive:!0});const g=p.map((e=>J({fileUrl:e.url,savePath:e.currentFilePath,token:s,key:c,fileName:e.fileName}))),y=yield Promise.all(g).finally((function(){m&&m.stop()}));let k=t;return y.forEach((e=>{const t=p.find((t=>t.url===e.fileUrl));if(t){const e=`[附件: ${t.fileName}](${r}/${t.fileName})`;k=k.replace(t.rawMd,e)}})),{mdData:k}}))}function K(e){return w(e)}function W(e){const t=[];return G(e,(function(e,o){"link"===e.type&&t.push({node:e,keyChain:o})})),t}function G(e,t,o=[]){t(e,o),Array.isArray(e.children)&&(o.push("children"),e.children.forEach(((e,n)=>{G(e,t,[...o,String(n)])})))}function Q(e){return $(this,void 0,void 0,(function*(){const{mdData:t,htmlData:o,savePath:r,attachmentsDir:i,articleTitle:s,token:c,key:u,ignoreAttachments:h}=e,f=function(e){return k(e)}(t),p=W(f);let m=p.filter((e=>/_lake_card.*?videoId/.test(e.node.url))),g=ee(o,"audio"),y=ee(o,"video");if(0===m.length&&0===g.length&&0===y.length)return{mdData:t};if("string"==typeof h){const e=h.split(",");if(m=m.filter((t=>{const o=t.node.url,n=o.lastIndexOf(".");if(-1===n)return!0;const r=o.slice(n+1);return!e.find((e=>e===r))})),g=g.filter((t=>{const o=t.audioId.lastIndexOf(".");if(-1===o)return!0;const n=t.audioId.slice(o+1);return!e.find((e=>e===n))})),y=y.filter((t=>{const o=t.videoId.lastIndexOf(".");if(-1===o)return!0;const n=t.videoId.slice(o+1);return!e.find((e=>e===n))})),0===m.length&&0===g.length&&0===y.length)return{mdData:t}}const w=d({text:`下载 "${s}" 的音视频中...`,stream:l});"test"!==a.NODE_ENV&&w.start();const I=n.resolve(r,i);v(I,{recursive:!0});let b=t;try{if(m.length>0){const t=yield function(e,t,o){return $(this,void 0,void 0,(function*(){const{key:r,token:i}=t,s=e.map((e=>$(this,void 0,void 0,(function*(){var t,s;const a=function(e){var t;try{const o=null!==(t=new URL(e).searchParams.get("_lake_card"))&&void 0!==t?t:"",n=decodeURIComponent(o),r=JSON.parse(n);return{name:(null==r?void 0:r.name)||"",videoId:(null==r?void 0:r.videoId)||""}}catch(e){return!1}}(e.node.url);if(!a)return!1;const l=yield Y({videoId:a.videoId,key:r,token:i});if(!l)return!1;const c=null!==(s=null!==(t=a.name)&&void 0!==t?t:a.videoId.split("/").at(-1))&&void 0!==s?s:a.videoId;return{videoInfo:Object.assign(Object.assign({},a),l),astNode:e,fileName:c,currentFilePath:n.join(o,c)}}))));return(yield Promise.all(s)).filter(z)}))}(m,e,I),o=t.map((e=>J({fileUrl:e.videoInfo.video,savePath:e.currentFilePath,token:c,key:u,fileName:e.videoInfo.name})));(yield Promise.all(o)).forEach((e=>{const o=t.find((t=>t.videoInfo.video===e.fileUrl));o&&(o.astNode.node.url=`${i}${n.sep}${o.fileName}`,o.astNode.node.children=[{type:"text",value:`音视频附件: ${o.videoInfo.name}`}])})),b=K(f)}if(g.length>0||y.length>0){const t=yield te(g,e,I,"audio"),o=yield te(y,e,I,"video"),r=[...t,...o].map((e=>$(this,void 0,void 0,(function*(){const t="audio"===e.type?e.videoInfo.fileName:e.videoInfo.name,o={fileUrl:"audio"===e.type?e.videoInfo.audio:e.videoInfo.video,savePath:e.currentFilePath,token:c,key:u,fileName:t};return Object.assign(Object.assign({},yield J(o)),{id:e.videoInfo.id,fileName:t})}))));(yield Promise.all(r)).forEach((e=>{const t=p.find((t=>new RegExp(`#${e.id}`,"gm").test(t.node.url)));t&&(t.node.url=`${i}${n.sep}${e.fileName}`,t.node.children=[{type:"text",value:`音视频附件: ${e.fileName}`}])})),b=K(f)}}finally{w&&w.stop()}return{mdData:b}}))}function Y(e){let t="https://www.yuque.com/api/video";const{videoId:o,token:n,key:r}=e,i=new URLSearchParams;return i.set("video_id",o),t=`${t}?${i.toString()}`,c.get(t,F({token:n,key:r})).then((({data:e,status:t})=>{const o=e.data;return 200===t&&"success"===o.status&&o.info})).catch((()=>!1))}function z(e){return!!e}const X=/name="audio" value="data:(.*?audioId.*?)".*?><\/card>/gm,Z=/name="video" value="data:(.*?videoId.*?)".*?><\/card>/gm;function ee(e,t){const o="video"===t?Z:X,n=e.match(o)||[];try{return n.map((e=>e.replace(o,"$1"))).map((e=>JSON.parse(decodeURIComponent(e))))}catch(e){return[]}}function te(e,t,o,r){return $(this,void 0,void 0,(function*(){const{key:i,token:s}=t,a=e.map((e=>$(this,void 0,void 0,(function*(){var t;const a=yield Y({videoId:"audio"===r?e.audioId:e.videoId,key:i,token:s});if(!a)return!1;const l=null!==(t="audio"===r?null==e?void 0:e.fileName:e.name)&&void 0!==t?t:e.id;return{videoInfo:Object.assign(Object.assign({},e),a),type:r,fileName:l,currentFilePath:n.join(o,l)}}))));return(yield Promise.all(a)).filter(z)}))}function oe(e){return $(this,void 0,void 0,(function*(){var o,n,r,i,s,c,h,f,p,m;const{articleInfo:v,progressBar:g,options:y,progressItem:k,oldProgressItem:w}=e,{token:$,key:I,convertMarkdownVideoLinks:E,hideFooter:N,ignoreImg:P,ignoreAttachments:L}=y,{bookId:U,itemUrl:T,savePath:S,saveFilePath:A,uuid:C,articleUrl:F,articleTitle:B,host:J,imageServiceDomains:V}=v,q={articleUrl:T,bookId:U,token:$,host:J,key:I},{httpStatus:K,apiUrl:W,response:G}=yield _(q);!function(){var e,t,o,n;const r=(null===(e=null==G?void 0:G.data)||void 0===e?void 0:e.created_at)||"",i=(null===(t=null==G?void 0:G.data)||void 0===t?void 0:t.content_updated_at)||"",s=(null===(o=null==G?void 0:G.data)||void 0===o?void 0:o.published_at)||"",a=(null===(n=null==G?void 0:G.data)||void 0===n?void 0:n.first_published_at)||"";k.createAt=r,k.contentUpdatedAt=i,k.publishedAt=s,k.firstPublishedAt=a}();const{needDownload:Y,isUpdateDownload:z}=function(e,t){const o={isFirstDownload:!0,isUpdateDownload:!1,needDownload:!0};if(!e.contentUpdatedAt||!t||!(null==t?void 0:t.contentUpdatedAt))return o;const n=new Date(e.contentUpdatedAt),r=new Date(t.contentUpdatedAt);if(!x(n)||!x(r))return o;if(n.getTime()>r.getTime())return{needDownload:!0,isUpdateDownload:!0,isFirstDownload:!1};if(n.getTime()===r.getTime())return{needDownload:!1,isUpdateDownload:!1,isFirstDownload:!1};return o}(k,w);if(!Y)return{needDownload:Y,isUpdateDownload:z,isDownloadFinish:!0};const X=null===(n=null===(o=null==G?void 0:G.data)||void 0===o?void 0:o.type)||void 0===n?void 0:n.toLocaleLowerCase();let Z="";if(X===b.SHEET){const{response:e}=yield _(q,!1);try{const t=null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.content,o=t?JSON.parse(t):{},n=null==o?void 0:o.sheet;Z=n?R(n):""}catch(e){const t=D.get(X);throw new Error(`download article Error: “${t}”解析错误 ${e}`)}}else{if([b.BOARD,b.TABLE].includes(X)){const e=D.get(X);throw new Error(`download article Error: 暂不支持“${e}”的文档`)}if("string"!=typeof(null===(i=null==G?void 0:G.data)||void 0===i?void 0:i.sourcecode))throw new Error(`download article Error: ${W}, http status ${K}`);Z=G.data.sourcecode,Z=function(e){const t=/!\[(.*?)\]\((http.*?latex.*?)\)/gm,o=e.match(t);let n=e;const r=e;try{null==o||o.forEach((e=>{var o,r;t.lastIndex=0;const i=null!==(r=null===(o=t.exec(e))||void 0===o?void 0:o[2])&&void 0!==r?r:"",{pathname:s,search:a}=new URL(i);if(!s.endsWith(".svg")&&a){const t=decodeURIComponent(a);n=n.replace(e,t.slice(1))}}))}catch(e){return r}return n}(Z)}const ee=function(e){if(!e)return[];const t=/!\[(.*?)\]\((.*?)\)/gm;let o=Array.from(e.match(t)||[]);return o=o.map((e=>(e=e.replace(t,"$2"),/^http.*/g.test(e)?e:""))).filter((e=>Boolean(e))),o}(Z),te=null!==(h=null===(c=null===(s=(yield _(q,!1)).response)||void 0===s?void 0:s.data)||void 0===c?void 0:c.content)&&void 0!==h?h:"";ee.length&&!P&&(Z=function(e,t,o){if(!o)return t;const n=/<card.*?name="image".*?value="data:(.*?)">(.*?)<\/card>/gm,r=[];let i,s=!0;for(;s||Boolean(i);)if(s=!1,i=n.exec(o),null==i?void 0:i[1])try{const e=decodeURIComponent(i[1]),t=JSON.parse(e);r.push((null==t?void 0:t.src)||"")}catch(e){r.push("")}const a=new Map;return e.forEach((e=>{const{origin:o,pathname:n}=new URL(e),i=`${o}${n}`,s=r.find(((e,t)=>{const o=new RegExp(`${i}.*?`).test(e);return o&&r.splice(t,1),o}));if(s){const o=new RegExp(e,"g"),n=a.get(e)||0;let r=0;t=t.replace(o,(e=>{let t=e;return r===n&&(t=s),r+=1,t})),a.set(e,n+1)}})),t}(ee,Z,te));const oe={toc:y.toc,articleTitle:B,articleUrl:F,articleUpdateTime:O(null!==(p=null===(f=null==G?void 0:G.data)||void 0===f?void 0:f.content_updated_at)&&void 0!==p?p:""),convertMarkdownVideoLinks:E,hideFooter:N},re=[];if(!L||"string"==typeof L)try{g.pause(),console.log("");Z=(yield H({mdData:Z,savePath:S,attachmentsDir:`./attachments/${j(C)}`,articleTitle:B,token:$,key:I,ignoreAttachments:L})).mdData}catch(e){re.push(`附件下载失败: ${e.message||"unknown error"}`)}finally{g.continue()}if(!L||"string"==typeof L)try{g.pause(),console.log("");Z=(yield Q({mdData:Z,htmlData:te,savePath:S,attachmentsDir:`./attachments/${j(C)}`,articleTitle:B,token:$,key:I,ignoreAttachments:L})).mdData}catch(e){re.push(`音视频下载失败: ${e.message||"unknown error"}`)}finally{g.continue()}if(ee.length&&!P){let e;g.pause(),console.log(""),"test"!==a.NODE_ENV&&(e=d({text:`下载 "${B}" 的图片中...`,stream:l}),e.start());let o=[],n=Z;try{const e=yield u.run(Z,{dist:S,imgDir:`./img/${C}`,isIgnoreConsole:!0,errorStillReturn:!0,referer:F||"",transform:e=>M(e=e.replace("x-oss-process=image%2Fwatermark%2C",""),V),timeout:18e4});o=e.errorInfo,n=e.data}catch(e){o=[e]}Z=n;const r=()=>{e&&e.stop(),g.continue()};if(o.length>0){const e=o[0];let n="图片下载失败(失败的以远程链接保存): ";throw n=e.url?`${n}${null===(m=e.error)||void 0===m?void 0:m.message} ${e.url.slice(0,20)}...`:`${n}${e.message}`,yield t(A,ne(Z,oe)),r(),new Error(`${n}`)}r()}try{if(yield t(A,ne(Z,oe)),re.length>0)throw new Error(re[0]);return{needDownload:Y,isUpdateDownload:z,isDownloadFinish:!0}}catch(e){throw new Error(`${e.message}`)}}))}function ne(e,t){const{articleTitle:o,articleUrl:n,toc:r,convertMarkdownVideoLinks:i,hideFooter:s}=t;let a=e;a=a.replace(/<a.*?>(\s*?)<\/a>/gm,"");const l=o?`# ${o}\n\n`:"";let c=r?h(a).content:"";c&&(c=`${c}\n\n---\n\n`);let d="";return s||(d="\n\n",t.articleUpdateTime&&(d+=`> 更新: ${t.articleUpdateTime} \n`),n&&(d+=`> 原文: <${n}>`)),a=`${l}${c}${a}${d}`,i&&(a=function(e){return e.replace(/\[(.*?)\]\((.*?)\.(mp4|mp3)\)/gm,((e,t,o,n)=>{const r="mp3"===n?"audio":"video";return`<${r} controls width="800" alt="${t}" src="${o+"."+n}"></${r}>`}))}(a)),a}function re(e,t){return $(this,void 0,void 0,(function*(){if(!function(e){if("function"==typeof URL.canParse)return URL.canParse(e);try{return new URL(e),!0}catch(e){return!1}}(e))throw new Error("Please enter a valid URL");const{bookId:r,tocList:i,bookName:s,bookDesc:a,bookSlug:l,host:d,imageServiceDomains:u}=yield((e,t)=>{const o=/decodeURIComponent\("(.+)"\)\);/m;return c.get(e,F(t)).then((({data:e="",status:t})=>200===t?e:"")).then((e=>{var t,n;const r=null!==(t=o.exec(e))&&void 0!==t?t:"";if(!r[1])return{};const i=JSON.parse(decodeURIComponent(r[1]));return i.book?{bookId:i.book.id,bookSlug:i.book.slug,tocList:i.book.toc||[],bookName:i.book.name||"",bookDesc:i.book.description||"",host:(null===(n=i.space)||void 0===n?void 0:n.host)||N,imageServiceDomains:i.imageServiceDomains||[]}:{}})).catch((e=>{var t;const o=null!==(t=null==e?void 0:e.message)&&void 0!==t?t:"";if(!o)throw new Error("unknown error");if(["getaddrinfo ENOTFOUND","read ECONNRESET","Client network socket disconnected before secure TLS connection was established"].some((e=>o.startsWith(e))))throw new Error("请检查网络(是否正常联网/是否开启了代理软件)");throw new Error(o)}))})(e,{token:t.token,key:t.key});if(!r)throw new Error("No found book id");if(!i||0===i.length)throw new Error("No found toc list");const h=n.resolve(t.distDir,s?j(s):String(r));yield o(h,{recursive:!0});const f=i.length,p=new U(h,f,t.incremental);if(yield p.init(),!t.incremental&&p.curr==f)return p.bar&&p.bar.stop(),void L.info(`√ 已完成: ${h}`);const m=new Map;(p.isDownloadInterrupted||t.incremental)&&p.progressInfo.forEach((e=>{m.set(e.toc.uuid,e)}));const v=e.replace(new RegExp(`(.*?/${l}).*`),"$1");yield function(e){return $(this,void 0,void 0,(function*(){const{articleUrlPrefix:t,total:r,uuidMap:i,tocList:s,bookPath:a,bookId:l,progressBar:c,host:d,options:u,imageServiceDomains:h=[]}=e;let f=0,p=0,m=0;const v=[],g=[],y=[];for(let e=0;e<r;e++){const t=s[e];if("string"!=typeof t.type)continue;const n=t.type.toLocaleLowerCase();if(n===I.TITLE||""!==t.child_uuid||n===I.LINK){let e=t;const r=[],s=[];for(;e;)r.unshift(j(e.title)),s.unshift(e.uuid),e=i.get(e.parent_uuid)?i.get(e.parent_uuid).toc:void 0;const l={path:r.map(j).join("/"),pathTitleList:r,pathIdList:s,toc:t};n===I.LINK?(m+=1,g.push(l)):yield o(`${a}/${r.map(j).join("/")}`,{recursive:!0}),i.set(t.uuid,l),n===b.DOC?yield k(t):yield c.updateProgress(l,n!==I.LINK)}else t.url&&(yield k(t))}function k(e){return $(this,void 0,void 0,(function*(){p+=1;let o={path:"",pathTitleList:[],pathIdList:[]};const r=e.type.toLocaleLowerCase();i.get(e.parent_uuid)&&(o=i.get(e.parent_uuid));const s=j(e.title),m=[...o.pathTitleList,s],g=[...o.pathIdList,e.uuid];let k=[...o.pathTitleList,`${s}.md`].map(j).join("/"),w=o.pathTitleList.map(j).join("/");r===b.DOC&&e.child_uuid&&(k=[...o.pathTitleList,s,"index.md"].map(j).join("/"),w=m.map(j).join("/"));const $={path:k,savePath:w,pathTitleList:m,pathIdList:g,toc:e};let I=!0;const D=`${t}/${e.url}`;try{const t={bookId:l,itemUrl:e.url,savePath:n.resolve(a,$.savePath),saveFilePath:n.resolve(a,$.path),uuid:e.uuid,articleUrl:D,articleTitle:e.title,host:d,imageServiceDomains:h},{isUpdateDownload:o}=yield oe({articleInfo:t,progressBar:c,options:u,progressItem:$,oldProgressItem:i.get(e.uuid)});o&&y.push({progressItem:$,articleInfo:t})}catch(e){I=!1,f+=1,v.push({articleUrl:D,errItem:$,errMsg:e.message,err:e})}i.set(e.uuid,$),yield c.updateProgress($,I)}))}if(m>0){L.warn("该知识库存在以下外链文章");for(const e of g)L.warn(`———— ✕ ${e.path} ${e.toc.url}`)}if(f>0){L.error(`本次执行总数${p}篇,✕ 失败${f}篇`);for(const e of v)L.error(`《${e.errItem.path}》: ${e.articleUrl}`),e.errMsg.split("\n").forEach((e=>{L.error(`———— ✕ ${e}`)}));L.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}y.length>0&&(L.info("以下文档有更新: "),y.forEach((e=>{L.info(`———— √ ${e.articleInfo.saveFilePath}`)})))}))}({articleUrlPrefix:v,total:f,uuidMap:m,tocList:i,bookPath:h,bookId:r,progressBar:p,host:d,options:t,imageServiceDomains:u});const g=new A({bookPath:h,bookName:s,bookDesc:a,uuidMap:m});yield g.genFile(),L.info(`√ 生成目录 ${n.resolve(h,"index.md")}`),p.curr===f&&L.info(`√ 已完成: ${h}`)}))}export{$ as _,L as l,re as m};
|
package/dist/es/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{m as main}from"./index-
|
|
1
|
+
export{m as main}from"./index-CjEfavqS.js";import"node:fs/promises";import"node:path";import"rand-user-agent";import"log4js";import"cli-progress";import"node:process";import"axios";import"ora";import"pull-md-img";import"markdown-toc";import"pako";import"node:crypto";import"node:fs";import"node:stream";import"node:util";import"mdast-util-from-markdown";import"mdast-util-to-markdown";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuque-dl",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.80",
|
|
4
4
|
"description": "yuque 知识库下载",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -31,11 +31,12 @@
|
|
|
31
31
|
"@types/progress": "^2.0.5",
|
|
32
32
|
"@types/semver": "^7.5.8",
|
|
33
33
|
"@types/web-bluetooth": "^0.0.20",
|
|
34
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
35
|
-
"@typescript-eslint/parser": "^
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^8.35.0",
|
|
35
|
+
"@typescript-eslint/parser": "^8.35.0",
|
|
36
36
|
"@vitest/coverage-v8": "^1.6.0",
|
|
37
37
|
"@vitest/ui": "^1.6.0",
|
|
38
38
|
"conventional-changelog-cli": "^5.0.0",
|
|
39
|
+
"eslint": "^8.57.1",
|
|
39
40
|
"msw": "^2.3.0",
|
|
40
41
|
"np": "^10.0.7",
|
|
41
42
|
"npm-run-all": "^4.1.5",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"mdast-util-to-markdown": "^2.1.0",
|
|
57
58
|
"ora": "^7.0.1",
|
|
58
59
|
"pako": "1.0.11",
|
|
59
|
-
"pull-md-img": "^0.0.
|
|
60
|
+
"pull-md-img": "^0.0.69",
|
|
60
61
|
"rand-user-agent": "1.0.109",
|
|
61
62
|
"semver": "^7.6.0",
|
|
62
63
|
"vitepress": "1.2.2"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare namespace Attachments {
|
|
2
|
+
interface IDownloadAttachments {
|
|
3
|
+
mdData: string;
|
|
4
|
+
savePath: string;
|
|
5
|
+
attachmentsDir: string;
|
|
6
|
+
articleTitle: string;
|
|
7
|
+
token?: string;
|
|
8
|
+
key?: string;
|
|
9
|
+
ignoreAttachments?: boolean | string;
|
|
10
|
+
}
|
|
11
|
+
interface IAttachmentsItem {
|
|
12
|
+
fileName: string;
|
|
13
|
+
url: string;
|
|
14
|
+
rawMd: string;
|
|
15
|
+
currentFilePath: string;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare namespace Video {
|
|
2
|
+
interface IDownloadVideo {
|
|
3
|
+
mdData: string;
|
|
4
|
+
htmlData: string;
|
|
5
|
+
savePath: string;
|
|
6
|
+
attachmentsDir: string;
|
|
7
|
+
articleTitle: string;
|
|
8
|
+
token?: string;
|
|
9
|
+
key?: string;
|
|
10
|
+
ignoreAttachments: boolean | string;
|
|
11
|
+
}
|
|
12
|
+
interface IGetVideoApiParams {
|
|
13
|
+
videoId: string;
|
|
14
|
+
token?: string;
|
|
15
|
+
key?: string;
|
|
16
|
+
}
|
|
17
|
+
interface IGetVideoApiResponse {
|
|
18
|
+
data: {
|
|
19
|
+
status: string;
|
|
20
|
+
info: IGetVideoApiInfo;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface IGetVideoApiInfo {
|
|
24
|
+
type: string;
|
|
25
|
+
cover?: string;
|
|
26
|
+
video: string;
|
|
27
|
+
audio: string;
|
|
28
|
+
origin: string;
|
|
29
|
+
state: number;
|
|
30
|
+
}
|
|
31
|
+
interface IGetVideoItem {
|
|
32
|
+
status: string;
|
|
33
|
+
audioId: string;
|
|
34
|
+
videoId: string;
|
|
35
|
+
fileName: string;
|
|
36
|
+
name: string;
|
|
37
|
+
fileSize: number;
|
|
38
|
+
id: string;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/types/types/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { ArticleResponse } from './ArticleResponse';
|
|
2
2
|
import { KnowledgeBase } from './KnowledgeBaseResponse';
|
|
3
3
|
import { ProgressBar } from '../utils/ProgressBar';
|
|
4
|
+
export interface CACHelpSection {
|
|
5
|
+
title?: string;
|
|
6
|
+
body: string;
|
|
7
|
+
}
|
|
4
8
|
export interface ICliOptions {
|
|
5
9
|
/** 目标目录 */
|
|
6
10
|
distDir: string;
|
|
7
11
|
/** 是否忽略图片 */
|
|
8
12
|
ignoreImg: boolean;
|
|
13
|
+
/** 是否忽略附件 */
|
|
14
|
+
ignoreAttachments: boolean | string;
|
|
9
15
|
/** 私有知识库 token */
|
|
10
16
|
token?: string;
|
|
11
17
|
/** 自定义token key(企业所有部署) */
|
|
@@ -44,7 +50,6 @@ export interface ArticleInfo {
|
|
|
44
50
|
uuid: string;
|
|
45
51
|
articleTitle: string;
|
|
46
52
|
articleUrl: string;
|
|
47
|
-
ignoreImg: boolean;
|
|
48
53
|
host?: string;
|
|
49
54
|
imageServiceDomains: string[];
|
|
50
55
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e,{writeFile as t,mkdir as o}from"node:fs/promises";import n from"node:path";import r from"rand-user-agent";import i from"log4js";import s from"cli-progress";import{env as a,stdout as l}from"node:process";import c from"axios";import d from"ora";import u from"pull-md-img";import h from"markdown-toc";import f from"pako";import p from"node:crypto";import{createWriteStream as m,mkdirSync as v}from"node:fs";import*as g from"node:stream";import{promisify as y}from"node:util";import{fromMarkdown as k}from"mdast-util-from-markdown";import{toMarkdown as w}from"mdast-util-to-markdown";function $(e,t,o,n){return new(o||(o=Promise))((function(r,i){function s(e){try{l(n.next(e))}catch(e){i(e)}}function a(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(s,a)}l((n=n.apply(e,t||[])).next())}))}var I,b;"function"==typeof SuppressedError&&SuppressedError,function(e){e.TITLE="title",e.LINK="link",e.DOC="doc"}(I||(I={})),function(e){e.BOARD="board",e.TABLE="table",e.SHEET="sheet",e.DOC="doc"}(b||(b={}));const D=new Map([[b.BOARD,"画板类型"],[b.TABLE,"数据表类型"],[b.SHEET,"表格类型"],[b.DOC,"文档类型"]]),E="_yuque_session",P="https://www.yuque.com",N="UXO91eVnUveQn8suOJaYMvBcWs9KptS8N5HoP8ezSeU4vqApZpy1CkPaTpkpQEx2W2mlhxL8zwS8UePwBgksUM0CTtAODbTTTDFD",U=(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 L{constructor(e,t,o=!1){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,this.incremental=o}init(){return $(this,void 0,void 0,(function*(){this.progressInfo=yield this.getProgress(),this.curr=this.incremental?0:this.progressInfo.length,this.curr!==this.total&&(this.curr>0&&this.curr!==this.total&&!this.incremental&&(this.isDownloadInterrupted=!0,U.info("根据上次数据继续断点下载")),this.bar=new s.SingleBar({format:"Download [{bar}] {percentage}% | {value}/{total}"},s.Presets.legacy),this.bar.start(this.total,this.curr))}))}getProgress(){return $(this,void 0,void 0,(function*(){let t=[];try{const o=yield e.readFile(this.progressFilePath,{encoding:"utf8"});t=JSON.parse(o)}catch(o){o&&"ENOENT"===o.code&&(yield e.writeFile(this.progressFilePath,JSON.stringify(t),{encoding:"utf8"}))}return t}))}updateProgress(t,o){return $(this,void 0,void 0,(function*(){if(this.curr!==this.total){if(this.curr=this.curr+1,o){const o=t.toc.uuid,n=this.progressInfo.find((e=>e.toc.uuid===o));n?Object.assign(n,t):this.progressInfo.push(t),yield 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(){var e;this.clearLine(2),null===(e=this.bar)||void 0===e||e.start(this.total,this.curr)}clearLine(e){var t;if(!(e<=0)&&"function"==typeof(null===(t=null===process||void 0===process?void 0:process.stderr)||void 0===t?void 0:t.cursorTo)){process.stderr.cursorTo(0);for(let t=0;t<e;t++)process.stderr.moveCursor(0,-1),process.stderr.clearLine(1)}}}function T({browser:e="chrome",os:t="mac os",device:o="desktop"}){o=o.toLowerCase(),e=e.toLowerCase(),t=t.toLowerCase();let n=r(o,e,t);if("chrome"===e)for(;n.includes("Chrome-Lighthouse")||n.includes("Gener8")||n.includes("HeadlessChrome")||n.includes("SMTBot");)n=r(o,e,t);if("safari"===e)for(;n.includes("Applebot");)n=r(o,e,t);return n}function S(e){return e.toString().padStart(2,"0")}function O(e){const t=new Date(e);if(isNaN(t.getTime()))return"";const o=t.getFullYear(),n=t.getMonth()+1,r=t.getDate(),i=t.getHours(),s=t.getMinutes(),a=t.getSeconds();return`${o}-${S(n)}-${S(r)} ${S(i)}:${S(s)}:${S(a)}`}function x(e){return e instanceof Date&&!isNaN(e.getTime())}class C{constructor(e){this.summaryInfo=e}genFile(){return $(this,void 0,void 0,(function*(){const{bookName:t,bookDesc:o,bookPath:n,uuidMap:r}=this.summaryInfo;let i=`# ${t}\n\n`;o&&(i+=`> ${o}\n\n`);let s=i;const a=[];r.forEach((e=>{const t=e.toc,o=t.parent_uuid,n=this.findTree(a,o),r={text:t.title.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/,""),id:t.uuid,level:1,type:"link"},i=t.type.toLocaleLowerCase();i===I.TITLE||""!==t.child_uuid?(r.type="title","boolean"!=typeof n?(Array.isArray(n.children)||(n.children=[]),r.level=n.level+1,n.children.push(r)):(r.level=1,a.push(r)),i===I.DOC&&(r.link=e.path)):(r.type="link",r.link=i===I.LINK?e.toc.url:e.path,"boolean"!=typeof n?(Array.isArray(n.children)||(n.children=[]),r.level=n.level+1,n.children.push(r)):(r.level=1,a.push(r)))}));s+=this.genSummaryContent(a,"");try{yield e.writeFile(`${n}/index.md`,s)}catch(e){U.error("Generate Summary Error")}return s}))}genSummaryContent(e,t){for(const o of e){if(o.type===I.TITLE)if(o.link){const e=o.link?o.link.replace(/\s/g,"%20"):o.link;t+=`\n${"".padStart(o.level+1,"#")} [${o.text}](${e})\n\n`}else t+=`\n${"".padStart(o.level+1,"#")} ${o.text}\n\n`;else if(o.type===I.LINK){const e=o.link?o.link.replace(/\s/g,"%20"):o.link;t+=`${1===o.level?"\n##":"-"} [${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 o=this.findTree(e.children,t);if(o)return o}return!1}findTree(e,t){if(!t)return!1;for(const o of e){const e=this.findIdItem(o,t);if(e)return e}return!1}}function F(e){const{key:t=E,token:o}=e,n={"user-agent":T({browser:"chrome",device:"desktop"})};return o&&(n.cookie=`${t}=${o};`),n}function _(e){const t={headers:F(e),beforeRedirect:t=>{t.headers=Object.assign(Object.assign({},(null==t?void 0:t.headers)||{}),F(e))}};return"test"===a.NODE_ENV&&(t.proxy=!1),t}const A=(e,t=!0)=>{const{articleUrl:o,bookId:n,token:r,key:i,host:s=P}=e;let a=`${s}/api/docs/${o}`;const l={book_id:String(n),merge_dynamic_data:String(!1)};t&&(l.mode="markdown");const d=new URLSearchParams(l).toString();return a=`${a}?${d}`,c.get(a,_({token:r,key:i})).then((({data:e,status:t})=>({apiUrl:a,httpStatus:t,response:e})))};function j(e){if(!e)return"";return e.replace(/[\\/:*?"<>|\n\r]/g,"_").replace(/\s/g,"").replace(/[\ud800-\udbff][\udc00-\udfff]/g,"")}const R=e=>{if(!e)return"";const t=f.inflate(e,{to:"string"}),o=JSON.parse(t);let n="";return o.forEach((e=>{const t=`## ${e.name}\n`,o=function(e){var t,o,n;let r=Object.keys(e);r=r.filter((t=>Object.keys(e[t]).some((o=>{var n,r;return null===(r=null===(n=null==e?void 0:e[t])||void 0===n?void 0:n[o])||void 0===r?void 0:r.v}))));let i=[];r.forEach((t=>{const o=e[t];o&&(i=i.concat(Object.keys(o)))}));const s=Math.max(...r.map((e=>Number(e)))),a=Math.max(...i.map((e=>Number(e))));if(s<0||a<0)return"";let l="";const c="ABCDEFGHIJKLMNOPQRSTUVWXYZ";let d=Array(a+1).fill(" ").map(((e,t)=>{const o=t%c.length;return c[o]})).join(" | ");d=`| |${d}|`;let u=Array(a+2).fill("---").join(" |");u=`|${u}|`,l=`${d}\n${u}\n`;for(let r=0;r<s+1;r++){const i=[];for(let s=0;s<a+1;s++){const a=(null===(o=null===(t=null==e?void 0:e[r])||void 0===t?void 0:t[s])||void 0===o?void 0:o.v)||null;a&&"string"==typeof a?i.push(a):a&&"object"==typeof a?"image"===(null==a?void 0:a.class)&&(null==a?void 0:a.src)?i.push(``):"checkbox"===(null==a?void 0:a.class)?i.push((null==a?void 0:a.value)?"[x] ":"[ ] "):"link"===(null==a?void 0:a.class)?i.push(`[${null==a?void 0:a.text}](${null==a?void 0:a.url})`):"select"===(null==a?void 0:a.class)&&i.push(null===(n=null==a?void 0:a.value)||void 0===n?void 0:n.join(",")):i.push(null)}l=`${l}${`| ${r+1} | ${i.join(" | ")}|`}\n`}return l}(e.data);n=`${n}\n${t}\n${o}`})),n};function M(e,t=[]){return function(e,t){try{const{host:o,pathname:n}=new URL(e);return!t.includes(o)&&Boolean(n)}catch(e){return!1}}(e,t)?`https://www.yuque.com/api/filetransfer/images?url=${encodeURIComponent(e)}&sign=${function(e){const t=p.createHash("sha256");return t.update(`${N}${e}`),t.digest("hex")}(e)}`:e}const B=y(g.finished);function J(e){return $(this,void 0,void 0,(function*(){const{fileUrl:t,savePath:o,token:n,key:r,fileName:i}=e;return c.get(t,Object.assign(Object.assign({},_({token:n,key:r})),{responseType:"stream"})).then((e=>$(this,void 0,void 0,(function*(){var n,r,s;if(null===(r=null===(n=e.request)||void 0===n?void 0:n.path)||void 0===r?void 0:r.startsWith("/login"))throw new Error(`"${i}" need token`);if(200===e.status){const n=m(o);return null===(s=e.data)||void 0===s||s.pipe(n),B(n).then((()=>({fileUrl:t,savePath:o})))}throw new Error(`response status ${e.status}`)}))))}))}const q=/\[(.*?)\]\((.*?)\)/g,V=/\[(.*?)\]\((.*?\.yuque\.com\/attachments.*?)\)/;function H(e){return $(this,void 0,void 0,(function*(){const{mdData:t,savePath:o,attachmentsDir:r,articleTitle:i,token:s,key:c}=e,u=(t.match(q)||[]).filter((e=>V.test(e)));if(0===u.length)return{mdData:t};const h=d({text:`下载 "${i}" 的附件中...`,stream:l});"test"!==a.NODE_ENV&&h.start();const f=n.resolve(o,r),p=u.map((e=>function(e,t){const[,o,r]=V.exec(e)||[];if(!r)return!1;const i=o||r.split("/").at(-1);if(!i)return!1;const s=n.join(t,i);return{fileName:i,url:r,rawMd:e,currentFilePath:s}}(e,f))).filter((e=>!1!==e));v(f,{recursive:!0});const m=p.map((e=>J({fileUrl:e.url,savePath:e.currentFilePath,token:s,key:c,fileName:e.fileName}))),g=yield Promise.all(m).finally((function(){h&&h.stop()}));let y=t;return g.forEach((e=>{const t=p.find((t=>t.url===e.fileUrl));if(t){const e=`[附件: ${t.fileName}](${r}/${t.fileName})`;y=y.replace(t.rawMd,e)}})),{mdData:y}}))}function K(e){const t=[];return W(e,(function(e,o){"link"===e.type&&t.push({node:e,keyChain:o})})),t}function W(e,t,o=[]){t(e,o),Array.isArray(e.children)&&(o.push("children"),e.children.forEach(((e,n)=>{W(e,t,[...o,String(n)])})))}const G=/name="audio" value="data:(.*?audioId.*?)".*?><\/card>/gm;function Q(e){return $(this,void 0,void 0,(function*(){const{mdData:t,htmlData:o,savePath:r,attachmentsDir:i,articleTitle:s,token:c,key:u}=e,h=function(e){return k(e)}(t),f=K(h).filter((e=>/_lake_card.*?videoId/.test(e.node.url))),p=function(e){const t=e.match(G)||[];try{return t.map((e=>e.replace(G,"$1"))).map((e=>JSON.parse(decodeURIComponent(e))))}catch(e){return[]}}(o);if(0===f.length&&0===p.length)return{mdData:t};const m=d({text:`下载 "${s}" 的音视频中...`,stream:l});"test"!==a.NODE_ENV&&m.start();const g=n.resolve(r,i);v(g,{recursive:!0});let y=t;try{if(f.length>0){const t=yield function(e,t,o){return $(this,void 0,void 0,(function*(){const{key:r,token:i}=t,s=e.map((e=>$(this,void 0,void 0,(function*(){var t,s;const a=function(e){var t;try{const o=null!==(t=new URL(e).searchParams.get("_lake_card"))&&void 0!==t?t:"",n=decodeURIComponent(o),r=JSON.parse(n);return{name:(null==r?void 0:r.name)||"",videoId:(null==r?void 0:r.videoId)||""}}catch(e){return!1}}(e.node.url);if(!a)return!1;const l=yield Y({videoId:a.videoId,key:r,token:i});if(!l)return!1;const c=null!==(s=null!==(t=a.name)&&void 0!==t?t:a.videoId.split("/").at(-1))&&void 0!==s?s:a.videoId;return{videoInfo:Object.assign(Object.assign({},a),l),astNode:e,fileName:c,currentFilePath:n.join(o,c)}}))));return(yield Promise.all(s)).filter(z)}))}(f,e,g),o=t.map((e=>J({fileUrl:e.videoInfo.video,savePath:e.currentFilePath,token:c,key:u,fileName:e.videoInfo.name})));(yield Promise.all(o)).forEach((e=>{const o=t.find((t=>t.videoInfo.video===e.fileUrl));o&&(o.astNode.node.url=`${i}${n.sep}${o.fileName}`,o.astNode.node.children=[{type:"text",value:`音视频附件: ${o.videoInfo.name}`}])})),y=function(e){return w(e)}(h)}if(p.length>0){const t=yield function(e,t,o){return $(this,void 0,void 0,(function*(){const{key:r,token:i}=t,s=e.map((e=>$(this,void 0,void 0,(function*(){var t;const s=yield Y({videoId:e.audioId,key:r,token:i});if(!s)return!1;const a=null!==(t=null==e?void 0:e.fileName)&&void 0!==t?t:e.id;return{audioInfo:Object.assign(Object.assign({},e),s),fileName:a,currentFilePath:n.join(o,a)}}))));return(yield Promise.all(s)).filter(z)}))}(p,e,g),o=t.map((e=>J({fileUrl:e.audioInfo.audio,savePath:e.currentFilePath,token:c,key:u,fileName:e.audioInfo.fileName}))),r=yield Promise.all(o);let s="\n\n> [yuque-dl warn]: 由于语雀markdown接口限制, 无法准确定位音频文件在文档中所在位置, 所以统一所有音频放到一起\n";r.forEach((e=>{const o=t.find((t=>t.audioInfo.audio===e.fileUrl));o&&(s+=`> - [音视频附件: ${o.audioInfo.fileName}](${i}${n.sep}${o.fileName})\n`)})),y+=s}}finally{m&&m.stop()}return{mdData:y}}))}function Y(e){let t="https://www.yuque.com/api/video";const{videoId:o,token:n,key:r}=e,i=new URLSearchParams;return i.set("video_id",o),t=`${t}?${i.toString()}`,c.get(t,_({token:n,key:r})).then((({data:e,status:t})=>{const o=e.data;return 200===t&&"success"===o.status&&o.info})).catch((()=>!1))}function z(e){return!!e}function X(e){return $(this,void 0,void 0,(function*(){var o,n,r,i,s,c,h,f,p,m;const{articleInfo:v,progressBar:g,options:y,progressItem:k,oldProgressItem:w}=e,{token:$,key:I,convertMarkdownVideoLinks:E,hideFooter:P}=y,{bookId:N,itemUrl:U,savePath:L,saveFilePath:T,uuid:S,articleUrl:C,articleTitle:F,ignoreImg:_,host:B,imageServiceDomains:J}=v,q={articleUrl:U,bookId:N,token:$,host:B,key:I},{httpStatus:V,apiUrl:K,response:W}=yield A(q);!function(){var e,t,o,n;const r=(null===(e=null==W?void 0:W.data)||void 0===e?void 0:e.created_at)||"",i=(null===(t=null==W?void 0:W.data)||void 0===t?void 0:t.content_updated_at)||"",s=(null===(o=null==W?void 0:W.data)||void 0===o?void 0:o.published_at)||"",a=(null===(n=null==W?void 0:W.data)||void 0===n?void 0:n.first_published_at)||"";k.createAt=r,k.contentUpdatedAt=i,k.publishedAt=s,k.firstPublishedAt=a}();const{needDownload:G,isUpdateDownload:Y}=function(e,t){const o={isFirstDownload:!0,isUpdateDownload:!1,needDownload:!0};if(!e.contentUpdatedAt||!t||!(null==t?void 0:t.contentUpdatedAt))return o;const n=new Date(e.contentUpdatedAt),r=new Date(t.contentUpdatedAt);if(!x(n)||!x(r))return o;if(n.getTime()>r.getTime())return{needDownload:!0,isUpdateDownload:!0,isFirstDownload:!1};if(n.getTime()===r.getTime())return{needDownload:!1,isUpdateDownload:!1,isFirstDownload:!1};return o}(k,w);if(!G)return{needDownload:G,isUpdateDownload:Y,isDownloadFinish:!0};const z=null===(n=null===(o=null==W?void 0:W.data)||void 0===o?void 0:o.type)||void 0===n?void 0:n.toLocaleLowerCase();let X="";if(z===b.SHEET){const{response:e}=yield A(q,!1);try{const t=null===(r=null==e?void 0:e.data)||void 0===r?void 0:r.content,o=t?JSON.parse(t):{},n=null==o?void 0:o.sheet;X=n?R(n):""}catch(e){const t=D.get(z);throw new Error(`download article Error: “${t}”解析错误 ${e}`)}}else{if([b.BOARD,b.TABLE].includes(z)){const e=D.get(z);throw new Error(`download article Error: 暂不支持“${e}”的文档`)}if("string"!=typeof(null===(i=null==W?void 0:W.data)||void 0===i?void 0:i.sourcecode))throw new Error(`download article Error: ${K}, http status ${V}`);X=W.data.sourcecode,X=function(e){const t=/!\[(.*?)\]\((http.*?latex.*?)\)/gm,o=e.match(t);let n=e;const r=e;try{null==o||o.forEach((e=>{var o,r;t.lastIndex=0;const i=null!==(r=null===(o=t.exec(e))||void 0===o?void 0:o[2])&&void 0!==r?r:"",{pathname:s,search:a}=new URL(i);if(!s.endsWith(".svg")&&a){const t=decodeURIComponent(a);n=n.replace(e,t.slice(1))}}))}catch(e){return r}return n}(X)}const ee=function(e){if(!e)return[];const t=/!\[(.*?)\]\((.*?)\)/gm;let o=Array.from(e.match(t)||[]);return o=o.map((e=>(e=e.replace(t,"$2"),/^http.*/g.test(e)?e:""))).filter((e=>Boolean(e))),o}(X),te=null!==(h=null===(c=null===(s=(yield A(q,!1)).response)||void 0===s?void 0:s.data)||void 0===c?void 0:c.content)&&void 0!==h?h:"";ee.length&&!_&&(X=function(e,t,o){if(!o)return t;const n=/<card.*?name="image".*?value="data:(.*?)">(.*?)<\/card>/gm,r=[];let i,s=!0;for(;s||Boolean(i);)if(s=!1,i=n.exec(o),null==i?void 0:i[1])try{const e=decodeURIComponent(i[1]),t=JSON.parse(e);r.push((null==t?void 0:t.src)||"")}catch(e){r.push("")}const a=new Map;return e.forEach((e=>{const{origin:o,pathname:n}=new URL(e),i=`${o}${n}`,s=r.find(((e,t)=>{const o=new RegExp(`${i}.*?`).test(e);return o&&r.splice(t,1),o}));if(s){const o=new RegExp(e,"g"),n=a.get(e)||0;let r=0;t=t.replace(o,(e=>{let t=e;return r===n&&(t=s),r+=1,t})),a.set(e,n+1)}})),t}(ee,X,te));const oe={toc:y.toc,articleTitle:F,articleUrl:C,articleUpdateTime:O(null!==(p=null===(f=null==W?void 0:W.data)||void 0===f?void 0:f.content_updated_at)&&void 0!==p?p:""),convertMarkdownVideoLinks:E,hideFooter:P},ne=[];try{g.pause(),console.log("");X=(yield H({mdData:X,savePath:L,attachmentsDir:`./attachments/${j(S)}`,articleTitle:F,token:$,key:I})).mdData}catch(e){ne.push(`附件下载失败: ${e.message||"unknown error"}`)}finally{g.continue()}try{g.pause(),console.log("");X=(yield Q({mdData:X,htmlData:te,savePath:L,attachmentsDir:`./attachments/${j(S)}`,articleTitle:F,token:$,key:I})).mdData}catch(e){ne.push(`音视频下载失败: ${e.message||"unknown error"}`)}finally{g.continue()}if(ee.length&&!_){let e;g.pause(),console.log(""),"test"!==a.NODE_ENV&&(e=d({text:`下载 "${F}" 的图片中...`,stream:l}),e.start());let o=[],n=X;try{const e=yield u.run(X,{dist:L,imgDir:`./img/${S}`,isIgnoreConsole:!0,errorStillReturn:!0,referer:C||"",transform:e=>M(e=e.replace("x-oss-process=image%2Fwatermark%2C",""),J),timeout:18e4});o=e.errorInfo,n=e.data}catch(e){o=[e]}X=n;const r=()=>{e&&e.stop(),g.continue()};if(o.length>0){const e=o[0];let n="图片下载失败(失败的以远程链接保存): ";throw n=e.url?`${n}${null===(m=e.error)||void 0===m?void 0:m.message} ${e.url.slice(0,20)}...`:`${n}${e.message}`,yield t(T,Z(X,oe)),r(),new Error(`${n}`)}r()}try{if(yield t(T,Z(X,oe)),ne.length>0)throw new Error(ne[0]);return{needDownload:G,isUpdateDownload:Y,isDownloadFinish:!0}}catch(e){throw new Error(`${e.message}`)}}))}function Z(e,t){const{articleTitle:o,articleUrl:n,toc:r,convertMarkdownVideoLinks:i,hideFooter:s}=t;let a=e;a=a.replace(/<a.*?>(\s*?)<\/a>/gm,"");const l=o?`# ${o}\n\n`:"";let c=r?h(a).content:"";c&&(c=`${c}\n\n---\n\n`);let d="";return s||(d="\n\n",t.articleUpdateTime&&(d+=`> 更新: ${t.articleUpdateTime} \n`),n&&(d+=`> 原文: <${n}>`)),a=`${l}${c}${a}${d}`,i&&(a=function(e){return e.replace(/\[(.*?)\]\((.*?)\.(mp4|mp3)\)/gm,((e,t,o,n)=>`<video controls width="800" alt="${t}" src="${o+"."+n}"></video>`))}(a)),a}function ee(e,t){return $(this,void 0,void 0,(function*(){if(!function(e){if("function"==typeof URL.canParse)return URL.canParse(e);try{return new URL(e),!0}catch(e){return!1}}(e))throw new Error("Please enter a valid URL");const{bookId:r,tocList:i,bookName:s,bookDesc:a,bookSlug:l,host:d,imageServiceDomains:u}=yield((e,t)=>{const o=/decodeURIComponent\("(.+)"\)\);/m;return c.get(e,_(t)).then((({data:e="",status:t})=>200===t?e:"")).then((e=>{var t,n;const r=null!==(t=o.exec(e))&&void 0!==t?t:"";if(!r[1])return{};const i=JSON.parse(decodeURIComponent(r[1]));return i.book?{bookId:i.book.id,bookSlug:i.book.slug,tocList:i.book.toc||[],bookName:i.book.name||"",bookDesc:i.book.description||"",host:(null===(n=i.space)||void 0===n?void 0:n.host)||P,imageServiceDomains:i.imageServiceDomains||[]}:{}})).catch((e=>{var t;const o=null!==(t=null==e?void 0:e.message)&&void 0!==t?t:"";if(!o)throw new Error("unknown error");if(["getaddrinfo ENOTFOUND","read ECONNRESET","Client network socket disconnected before secure TLS connection was established"].some((e=>o.startsWith(e))))throw new Error("请检查网络(是否正常联网/是否开启了代理软件)");throw new Error(o)}))})(e,{token:t.token,key:t.key});if(!r)throw new Error("No found book id");if(!i||0===i.length)throw new Error("No found toc list");const h=n.resolve(t.distDir,s?j(s):String(r));yield o(h,{recursive:!0});const f=i.length,p=new L(h,f,t.incremental);if(yield p.init(),!t.incremental&&p.curr==f)return p.bar&&p.bar.stop(),void U.info(`√ 已完成: ${h}`);const m=new Map;(p.isDownloadInterrupted||t.incremental)&&p.progressInfo.forEach((e=>{m.set(e.toc.uuid,e)}));const v=e.replace(new RegExp(`(.*?/${l}).*`),"$1");yield function(e){return $(this,void 0,void 0,(function*(){const{articleUrlPrefix:t,total:r,uuidMap:i,tocList:s,bookPath:a,bookId:l,progressBar:c,host:d,options:u,imageServiceDomains:h=[]}=e;let f=0,p=0,m=0;const v=[],g=[],y=[];for(let e=0;e<r;e++){const t=s[e];if("string"!=typeof t.type)continue;const n=t.type.toLocaleLowerCase();if(n===I.TITLE||""!==t.child_uuid||n===I.LINK){let e=t;const r=[],s=[];for(;e;)r.unshift(j(e.title)),s.unshift(e.uuid),e=i.get(e.parent_uuid)?i.get(e.parent_uuid).toc:void 0;const l={path:r.map(j).join("/"),pathTitleList:r,pathIdList:s,toc:t};n===I.LINK?(m+=1,g.push(l)):yield o(`${a}/${r.map(j).join("/")}`,{recursive:!0}),i.set(t.uuid,l),n===b.DOC?yield k(t):yield c.updateProgress(l,n!==I.LINK)}else t.url&&(yield k(t))}function k(e){return $(this,void 0,void 0,(function*(){p+=1;let o={path:"",pathTitleList:[],pathIdList:[]};const r=e.type.toLocaleLowerCase();i.get(e.parent_uuid)&&(o=i.get(e.parent_uuid));const s=j(e.title),m=[...o.pathTitleList,s],g=[...o.pathIdList,e.uuid];let k=[...o.pathTitleList,`${s}.md`].map(j).join("/"),w=o.pathTitleList.map(j).join("/");r===b.DOC&&e.child_uuid&&(k=[...o.pathTitleList,s,"index.md"].map(j).join("/"),w=m.map(j).join("/"));const $={path:k,savePath:w,pathTitleList:m,pathIdList:g,toc:e};let I=!0;const D=`${t}/${e.url}`;try{const t={bookId:l,itemUrl:e.url,savePath:n.resolve(a,$.savePath),saveFilePath:n.resolve(a,$.path),uuid:e.uuid,articleUrl:D,articleTitle:e.title,ignoreImg:u.ignoreImg,host:d,imageServiceDomains:h},{isUpdateDownload:o}=yield X({articleInfo:t,progressBar:c,options:u,progressItem:$,oldProgressItem:i.get(e.uuid)});o&&y.push({progressItem:$,articleInfo:t})}catch(e){I=!1,f+=1,v.push({articleUrl:D,errItem:$,errMsg:e.message,err:e})}i.set(e.uuid,$),yield c.updateProgress($,I)}))}if(m>0){U.warn("该知识库存在以下外链文章");for(const e of g)U.warn(`———— ✕ ${e.path} ${e.toc.url}`)}if(f>0){U.error(`本次执行总数${p}篇,✕ 失败${f}篇`);for(const e of v)U.error(`《${e.errItem.path}》: ${e.articleUrl}`),e.errMsg.split("\n").forEach((e=>{U.error(`———— ✕ ${e}`)}));U.error("o(╥﹏╥)o 由于网络波动或链接失效以上下载失败,可重新执行命令重试(PS:不会影响已下载成功的数据)")}y.length>0&&(U.info("以下文档有更新: "),y.forEach((e=>{U.info(`———— √ ${e.articleInfo.saveFilePath}`)})))}))}({articleUrlPrefix:v,total:f,uuidMap:m,tocList:i,bookPath:h,bookId:r,progressBar:p,host:d,options:t,imageServiceDomains:u});const g=new C({bookPath:h,bookName:s,bookDesc:a,uuidMap:m});yield g.genFile(),U.info(`√ 生成目录 ${n.resolve(h,"index.md")}`),p.curr===f&&U.info(`√ 已完成: ${h}`)}))}export{$ as _,U as l,ee as m};
|