@deveco-test/deveco-cli 1.3.0-Test.9 → 1.3.1-Test.2

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.
@@ -1,65 +1 @@
1
- import*as x from"fs";import*as Q from"path";import Ci from"proper-lockfile";import Ri from"ora";import*as b from"fs";import*as ot from"path";var Ot=["harmonyos-guides","harmonyos-references","best-practices","harmonyos-faqs","harmonyos-releases","harmonyos-roadmap"],ct={"harmonyos-guides":"\u5F00\u53D1\u6307\u5357","harmonyos-references":"API\u53C2\u8003","best-practices":"\u6700\u4F73\u5B9E\u8DF5","harmonyos-faqs":"FAQ","harmonyos-releases":"\u7248\u672C\u8BF4\u660E","harmonyos-roadmap":"\u53D8\u66F4\u9884\u544A"};var F="1.9.1",Ui=48*1024*1024,Ae=280,De=6,Ie=100,Te=3,we=28,Pt=10,Ce=/API参考|APIReference/i;var Re=6,ut=700,Lt=250,Bt=400,Ne=1320,Oe=120,Pe=450,Le=250,Be=500,Me=480,ke=80,Fe=200,ve=60,ze=200,He=40,je=200,Ze=200,Ue=40,v=500,$e=Object.fromEntries(Ot.map((t,e)=>[ct[t],e])),R=Object.fromEntries(Ot.map((t,e)=>[t,e]));import*as J from"fs";import*as m from"path";import{fileURLToPath as Ye}from"url";import*as N from"fs";import*as Qe from"path";import{homedir as pr}from"os";import*as Ge from"fs";import*as y from"path";function Mt(t,e){let n=y.relative(e,t);return n===""||!y.isAbsolute(n)&&!n.startsWith(`..${y.sep}`)&&n!==".."}function z(t){let e=y.resolve(t),n=[],r=e;for(;;)try{let o=Ge.realpathSync(r);return n.length===0?o:y.join(o,...n.reverse())}catch(o){if(o.code!=="ENOENT")throw o;let i=y.dirname(r);if(i===r)return e;n.push(y.basename(r)),r=i}}function Xe(t,e){let n=z(e),r=z(t);return Mt(r,n)?r:null}function kt(t){let e=t.trim();return(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))&&(e=e.slice(1,-1).trim()),e}function We(t){let e=kt(t);if(!e)throw new Error("Path must not be empty.");return z(e)}var gr="deveco-cli",Ft,L=class extends Error{constructor(e){super(e),this.name="CliDataDirError"}};function qe(){let t=process.env.DEVECO_CLI_DATA_DIR,n=(t===void 0||t===""?"":kt(t))||Qe.join(pr(),".local","share",gr);try{return We(n)}catch(r){throw new L(r instanceof Error?r.message:String(r))}}async function Je(){let t=qe();await N.promises.mkdir(t,{recursive:!0});let e;try{e=await N.promises.realpath(t)}catch(r){throw new L(`DEVECO_CLI_DATA_DIR is not usable: ${r instanceof Error?r.message:String(r)}`)}if(!(await N.promises.stat(e)).isDirectory())throw new L("DEVECO_CLI_DATA_DIR must be a writable directory.");return Ft=e,e}function q(){if(Ft!==void 0)return Ft;let t=qe();try{if(N.existsSync(t))return N.realpathSync(t)}catch{}return t}var hr="docs";function H(){return m.join(q(),hr)}function g(){return m.join(H(),".index")}function lt(){return m.join(g(),"build.lock")}function Y(){return m.join(g(),"build-status.json")}function j(){return m.join(g(),"build-meta.json")}function Z(){return m.join(g(),"search.db")}function V(){return m.join(g(),"sqlite-backend.json")}function K(){return m.join(g(),"jieba-backend.json")}function I(){return m.join(g(),".tmp")}function Sr(){return m.join(q(),"logs")}function vt(){return m.join(Sr(),"doc-init.log")}function yr(t,e){let n=e;for(;!n.endsWith(`${m.sep}dist`)&&n!==m.dirname(n);)n=m.dirname(n);return n}function Ve(t,e){return m.dirname(yr(t,e))}function Ke(){let t=Ye(import.meta.url),e=m.dirname(t);return t.includes(`${m.sep}dist${m.sep}`)?Ve(t,e):m.join(e,"..","..","..")}function xr(...t){let e=Ye(import.meta.url),n=m.dirname(e);return e.includes(`${m.sep}dist${m.sep}`)?[m.join(Ve(e,n),...t)]:[m.join(n,"..","..","..",...t)]}function tn(...t){let e=Ke(),n=J.realpathSync(e);for(let r of xr(...t))try{let o=J.lstatSync(r);if(o.isSymbolicLink()||!o.isFile())throw new Error(`Unsafe documentation package asset: ${t.join("/")} must be a regular file.`);let i=J.realpathSync(r);if(!Mt(i,n))throw new Error(`Unsafe documentation package asset: ${t.join("/")} is outside the package.`);return i}catch(o){if(o.code!=="ENOENT")throw o}return null}function B(){return tn("docs.zip")}function zt(){return tn("index.zip")}function en(){return m.join(Ke(),"index","data")}import*as T from"fs";import*as M from"path";var w=["harmonyos-terms.txt","harmonyos-synonyms.json","harmonyos-stopwords.txt"],Ht=class extends Error{constructor(e){super(e),this.name="LexiconNotFoundError"}};var jt=null;function Zt(t){jt=t}function nn(){if(jt)return jt;let t=g();if(w.every(o=>T.existsSync(M.join(t,o))))return t;let n=en();if(w.every(o=>T.existsSync(M.join(n,o))))return n;throw new Ht("Lexicon files not found. Install the documentation index first (index.zip).")}function tt(t){let e=M.join(nn(),t);return T.readFileSync(e,"utf-8")}function rn(t,e){return T.readFileSync(M.join(e,t),"utf-8")}async function on(t,e=nn()){await T.promises.mkdir(t,{recursive:!0});for(let n of w){let r=M.join(e,n),o=M.join(t,n);await T.promises.copyFile(r,o)}}import*as Ut from"fs";import*as Er from"yauzl";function $t(){let t=B();return t!==null&&Ut.existsSync(t)}import*as S from"fs";import*as C from"path";import sn from"adm-zip";import*as et from"fs";import*as mt from"path";var dt=class extends Error{constructor(e){super(`Unsafe documentation path: ${e}`),this.name="DocPathSafetyError"}};function Wt(t){return t instanceof L||t instanceof dt||t instanceof Error&&(t.name==="CliDataDirError"||t.name==="DocPathSafetyError")}function Qt(t){return new dt(t)}function _r(){return z(q())}function Xt(t,e,n){let r=Xe(t,e);if(r===null)throw Qt(`${n} resolves outside the data directory.`);return r}async function Gt(t,e){await et.promises.mkdir(t,{recursive:!0});let n=Xt(t,e,"directory");if(!(await et.promises.stat(n)).isDirectory())throw Qt("path must be a directory.")}function nt(t){let e=_r();try{let n=Xt(t,e,"file");if(!et.statSync(n).isFile())throw Qt("path must be a regular file.")}catch(n){if(n.code==="ENOENT"){Xt(mt.dirname(t),e,"file parent");return}throw n}}async function rt(t={}){let e=t.mode??"write",n=await Je();await Gt(H(),n),await Gt(g(),n),e==="write"&&await Gt(I(),n);for(let r of[Z(),j(),Y(),lt(),K(),V(),...w.map(o=>mt.join(g(),o))])nt(r)}var qt=["search.db","build-meta.json",...w],br=["corpus.json","corpus-offsets.json","orama.dpack"];async function Ar(t){for(let e of br)await S.promises.rm(C.join(t,e),{force:!0})}async function Dr(t){let e=await S.promises.readdir(t,{withFileTypes:!0});for(let n of e)n.name!==".index"&&await S.promises.rm(C.join(t,n.name),{recursive:!0,force:!0})}function an(t){let n=new sn(t).getEntry("build-meta.json");if(!n)throw new Error("index.zip is missing build-meta.json");return JSON.parse(n.getData().toString("utf-8"))}async function Ir(t){let e=g();await S.promises.mkdir(e,{recursive:!0});for(let n of qt){let r=C.join(e,n);await S.promises.rm(r,{force:!0}),await S.promises.rename(C.join(t,n),r)}await Ar(e),await S.promises.rm(I(),{recursive:!0,force:!0})}function cn(t){let e=zt();if(!e)return!1;try{let n=an(e);return n.indexVersion===F&&n.docsZipSha256===t&&n.segmentCount>0}catch{return!1}}async function un(t){await rt({mode:"write"});let e=zt();if(!e)throw new Error("index.zip not found");let n=an(e);if(n.docsZipSha256!==t)throw new Error("Bundled index.zip does not match docs.zip. Rebuild index.zip with npm run build:index.");if(n.segmentCount<=0)throw new Error("Bundled index.zip is empty");let r=I();await S.promises.rm(r,{recursive:!0,force:!0}),await S.promises.mkdir(r,{recursive:!0});let o=new sn(e);for(let s of qt){let a=o.getEntry(s);if(!a)throw new Error(`index.zip is missing ${s}`);await S.promises.writeFile(C.join(r,s),a.getData())}let i=JSON.parse(await S.promises.readFile(C.join(r,"build-meta.json"),"utf-8"));if(!S.existsSync(C.join(r,"search.db")))throw new Error("index.zip is missing search.db");return await Ir(r),await S.promises.mkdir(H(),{recursive:!0}),await Dr(H()),i}async function ln(){await S.promises.rm(I(),{recursive:!0,force:!0});let t=g();for(let e of qt)await S.promises.rm(C.join(t,e),{force:!0})}import{createHash as dn}from"crypto";import*as mn from"fs";async function ft(t){return new Promise((e,n)=>{let r=dn("sha256"),o=mn.createReadStream(t);o.on("data",i=>r.update(i)),o.on("error",n),o.on("end",()=>e(r.digest("hex")))})}function fn(t){return dn("sha256").update(t,"utf8").digest("hex")}function pn(t,e){let n=e?rn(t,e):tt(t);return fn(n)}function pt(t){return pn("harmonyos-synonyms.json",t)}function gt(t){return pn("harmonyos-terms.txt",t)}var Tr={state:"idle",phase:0,phaseLabel:"Idle",current:0,total:0,message:"",startedAt:0,updatedAt:0,error:null};async function gn(){try{let t=await b.promises.readFile(Y(),"utf-8");return JSON.parse(t)}catch{return{...Tr}}}async function Jt(t){let e=Y();await b.promises.mkdir(ot.dirname(e),{recursive:!0}),await b.promises.writeFile(e,JSON.stringify(t,null,2))}function hn(t){let e=Date.now();return{state:"extracting",phase:1,phaseLabel:"Extracting documentation",current:0,total:0,message:t,startedAt:e,updatedAt:e,error:null}}async function O(t){let n={...await gn(),...t,updatedAt:Date.now()};return await Jt(n),n}async function Yt(){let t=B();return t?ft(t):null}async function Vt(){try{let t=await b.promises.readFile(j(),"utf-8");return JSON.parse(t)}catch{return null}}async function Kt(t=!1){if(t)return"no-index";let e=await Vt();if(!e||e.segmentCount===0)return"no-index";let n=await Yt();return n&&e.docsZipSha256!==n?"docs-changed":e.indexVersion!==F?"engine-upgraded":e.termsHash!==gt()?"terms-changed":e.synonymsHash!==pt()?"synonyms-changed":null}function te(){if(!$t()||!b.existsSync(Z())||!b.existsSync(j()))return!1;let t=ot.dirname(Z());if(!w.every(e=>b.existsSync(ot.join(t,e))))return!1;try{let e=b.readFileSync(j(),"utf-8");return JSON.parse(e).segmentCount>0}catch{return!1}}async function Sn(t=!1){return t?!0:$t()?te()?await Kt()!==null:!0:!1}import*as xe from"fs";import*as Ee from"path";import Ei from"adm-zip";var yn=new Set(["picker","dialog","sheet","panel","popup","menu","layout","view","gesture","animation","transition","recognizer","manager","kit"]);var xn=new Set(["a","an","and","api","app","application","arkts","arkui","for","get","harmonyos","how","in","oh","ohos","on","or","set","the","to","use","using","what","when","where","which","with","without","data","file","main","model","name","network","stage","system","type","user"]),En=new Set(["ability","extension","module","service","context","options","config","info","event","code","state","type","data","request","response","client","server","handler","helper","utils","factory","builder","listener","callback","observer","provider","consumer","delegate","adapter","driver","buffer","stream","channel","session","task","worker","controller","component","container","attribute","descriptor","modifier","validator","parser","formatter","encoder","decoder","filter","converter","generator","iterator","dispatcher","resolver","scanner","tracker","monitor","scheduler","renderer","loader","subscriber","proxy","button","surface","stack","heap","map","set","array","list"]);var wr=/@ohos\.[a-z][a-zA-Z0-9.]+/gi,Cr=/\b[a-z][a-z0-9]*[A-Z][a-zA-Z0-9]+\b/g,Rr=/[A-Z][a-zA-Z0-9]{2,}/g,Nr=/@[A-Z][a-zA-Z0-9]*/g,Or=/[a-z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]+/g,_n=6,Pr=/^[a-z][a-z0-9]{2,}$/,Lr=/^([a-z][a-z0-9]{2,})\s+([a-z][a-z0-9]{2,})$/,Br=/^@ohos\.[a-z][a-zA-Z0-9.]+$/i,Mr=/^[a-z][a-z0-9]*[A-Z][a-zA-Z0-9]+$/,kr=/^[A-Z][a-zA-Z0-9]+$/;function ee(t){return Br.test(t)}function Fr(t){return Mr.test(t)&&t.length>=_n}function vr(t){return kr.test(t)}function ne(t){return ee(t)||Fr(t)||vr(t)}function zr(t){let e=t.trim().toLowerCase();return En.has(e)?!1:yn.has(e)}function Hr(t,e){let n=e.trim().charAt(0).toUpperCase(),r=e.trim().slice(1).toLowerCase();return`${t.trim().toLowerCase()}${n}${r}`}function ht(t){let n=t.replace(/^@ohos\./i,"").split(".").filter(Boolean);return n[n.length-1]?.trim()||void 0}function re(t){return[...t.matchAll(wr)].map(e=>e[0])}function oe(t,e=_n){let n=[];for(let r of t.matchAll(Cr))r[0].length>=e&&n.push(r[0]);return n}function U(t){return t.filter(e=>{let n=e.toLowerCase();return!t.some(r=>{if(r===e)return!1;let o=r.toLowerCase();return o.length>n.length&&o.endsWith(n)&&n.length>=4})})}function A(t,e){let n=e.trim();if(!n)return;t.add(n);let r=n.toLowerCase();r!==n&&t.add(r)}function jr(t){let e=new Set;A(e,t);let n=ht(t);return n&&A(e,n),U([...e])}function ie(t){if(ee(t))return jr(t);let e=new Set;return A(e,t),U([...e])}function se(t){let e=t.trim();if(/[A-Z]/.test(e))return null;let n=e.match(Lr);if(!n)return null;let r=n[1].toLowerCase(),o=n[2].toLowerCase();if(!Pr.test(r)||xn.has(r)||!zr(o))return null;let i=Hr(r,o);return{first:r,second:o,camelCase:i,lower:i.toLowerCase()}}function bn(t){let e=se(t.trim());return!e||e.second!=="manager"?null:e}function ae(t,e,n){let r=n.toLowerCase(),o=new RegExp(`@ohos\\.[^\\s(]*${n}`,"i");for(let i of[t,e])if(i&&(i.toLowerCase().includes(r)||o.test(i)))return!0;return!1}function An(t){let e=t.trim();if(ne(e))return ie(e);let n=new Set;for(let r of re(t)){A(n,r);let o=ht(r);o&&A(n,o)}for(let r of oe(t))A(n,r);for(let r of t.matchAll(Nr))n.add(r[0]);for(let r of t.matchAll(Or))n.add(r[0]);for(let r of t.matchAll(Rr))r[0].length>=4&&n.add(r[0]);return U([...n])}function Dn(t){let e=t.trim();if(ne(e))return ie(e);let n=new Set,r=se(e);r&&A(n,r.camelCase);for(let o of An(e))n.add(o);for(let o of e.matchAll(/\b[a-z][a-zA-Z0-9]{3,}\b/g)){let i=o[0];i!==i.toLowerCase()&&n.add(i)}return U([...n])}var D={pureApiSymbol:/^[A-Z][a-zA-Z0-9]+$/,stageModelExact:/^Stage\s*模型$/i,stageModelEnglishExact:/^stage\s+model$/i,stageModel:/Stage\s*模型/i,stageModelEntryPage:/Stage\s*模型.*EntryAbility.*(页面|新页面)/,declarePermissionBoost:/声明.*权限|应用权限.*声明|如何声明应用权限/,declarePermissionCatalog:/如何声明应用权限/,declarePermissionTokens:/如何声明应用权限|声明应用权限/,uiAbilityLifecycleBoost:/UIAbility.*生命周期|生命周期.*UIAbility|UIAblity/i,uiAbilityLifecycleCatalog:/UIAblity.*生命周期|UIAbility.*生命周期/i,entryAbilityPage:/EntryAbility.*(页面|启动|跳转|新页面)/,stateDecoratorBoost:/@State|@Prop|@Link|@Provide|@Consume/,stateDecoratorCatalog:/@State\s*装饰器|@Prop\s*装饰器|@Link\s*装饰器/,stateManagement:/状态管理原理/,routerRoute:/Router\s+路由/,dialogPopupExact:/^Dialog\s+弹窗$/,dialogPopupBoost:/Dialog\s+弹窗/};function Tn(t){return D.pureApiSymbol.test(t.trim())}function In(t){let e=t.trim();return D.stageModelExact.test(e)||D.stageModelEnglishExact.test(e)}var Zr=[{matches:t=>D.uiAbilityLifecycleBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.85},{catalog:"harmonyos-references",multiplier:.65},{catalog:"harmonyos-faqs",multiplier:.82}]},{matches:t=>In(t),weights:[{catalog:"harmonyos-guides",multiplier:1.85},{catalog:"harmonyos-references",multiplier:.55},{catalog:"harmonyos-faqs",multiplier:.85}]},{matches:t=>!In(t)&&D.stageModel.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"harmonyos-references",multiplier:.65}]},{matches:t=>D.entryAbilityPage.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.75},{catalog:"harmonyos-references",multiplier:.48}]},{matches:t=>D.declarePermissionBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"best-practices",multiplier:.68}]},{matches:t=>D.stateDecoratorBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.75},{catalog:"harmonyos-references",multiplier:.42}]},{matches:t=>D.stateManagement.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.6},{catalog:"best-practices",multiplier:.78}]},{matches:t=>D.routerRoute.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"harmonyos-references",multiplier:1.4},{catalog:"harmonyos-faqs",multiplier:.72},{catalog:"best-practices",multiplier:.72}]},{matches:t=>D.dialogPopupBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"harmonyos-faqs",multiplier:.72},{catalog:"best-practices",multiplier:.72}]}];function Ur(t,e){for(let{catalog:n,multiplier:r}of e){let o=R[n];t.set(o,(t.get(o)??1)*r)}}function wn(t,e){for(let n of Zr)n.matches(t)&&Ur(e,n.weights)}import*as $ from"fs";import*as Rn from"path";function k(t){if(process.env.DEVECO_CLI_DEBUG){let e=typeof t=="function"?t():t;console.log(`[DEBUG] ${e}`)}}var St=null,ce=null,ue=null;function $r(){return $.existsSync(K())}function Gr(t){let e=K(),n={backend:"jieba-wasm",reason:"native-jieba-load-failed",message:t,createdAt:new Date().toISOString()};$.mkdirSync(Rn.dirname(e),{recursive:!0}),nt(e),$.writeFileSync(e,JSON.stringify(n,null,2))}function Xr(){if(St)return St;let t=tt("harmonyos-stopwords.txt");return St=new Set(t.split(`
2
- `).map(e=>e.trim()).filter(Boolean)),St}function Wr(t){let e=[];for(let n=0;n<t.length;n++){let r=t[n]?.trim();if(!r)continue;let o=t[n+1]?.trim();if(r==="@"&&o&&/^[A-Z][a-zA-Z0-9]*$/.test(o)){e.push(`@${o}`),n+=1;continue}e.push(r)}return e}function Qr(t){let e=Xr(),n=[];for(let r of Wr(t)){let o=r.trim();!o||e.has(o)||(n.push(o.toLowerCase()),/[A-Z]/.test(o)&&/[a-zA-Z]/.test(o)&&n.push(o))}return n}async function Nn(t){let{dict:e}=await import("@node-rs/jieba/dict.js"),n=t.withDict(e),r=tt("harmonyos-terms.txt");return n.loadDict(Buffer.from(r,"utf-8")),n}async function qr(){let{Jieba:t}=await import("@node-rs/jieba");return Nn(t)}async function Cn(){let{Jieba:t}=await import("@node-rs/jieba-wasm32-wasi");return Nn(t)}async function Jr(){if($r())return await Cn();try{let e=await qr();return k("doc-index: using @node-rs/jieba backend"),e}catch(e){let n=e instanceof Error?e.message:String(e);Gr(n),k(`doc-index: @node-rs/jieba unavailable (${n}); falling back to wasm32-wasi`)}let t=await Cn();return k("doc-index: using @node-rs/jieba-wasm32-wasi backend"),t}async function G(){return ce||(ue||(ue=Jr().then(t=>(ce=t,t))),ue)}async function Yr(t){let e=await G();return Qr(e.cutForSearch(t,!0))}async function yt(t,e){let n=t.trim();if(!n||e<=0)return"";let r=(await Yr(n)).join(" ");return r.length<=e?r:r.slice(0,e)}async function Vr(t,e){let n=[];for(let o of t){let i=o.trim();i&&(n.push(i.toLowerCase()),/[A-Z]/.test(i)&&n.push(i))}let r=[...new Set(n)].join(" ");return r.length<=e?r:r.slice(0,e)}async function xt(t){let e=!!t.sectionTitle.trim(),n=t.titleTokens.trim(),r=e?Me:Ne,o=e?Fe:Pe,i=e?await Vr(t.apiSymbols,o):await yt(t.apiSymbols.join(" "),o),a=(await Promise.all([yt(n,e?ke:Oe),Promise.resolve(i),yt(t.headingsText,e?ve:Le),yt(t.bodySample,e?ze:Be)])).filter(Boolean).join(" ");return a.length<=r?a:a.slice(0,r)}var On=["harmonyos-releases","harmonyos-roadmap"],Kr=new Set(On.map(t=>R[t])),Ra=On.map(t=>`${ct[t]}/`);function to(t){return Kr.has(t)}function Pn(t){let e=[],n=[];for(let r of t)to(r.catalog_id)?n.push(r):e.push(r);return[...e,...n]}var eo=[{pattern:/@ohos\./i,catalog:"harmonyos-references",multiplier:1.5},{pattern:/@[A-Z][a-zA-Z]+/,catalog:"harmonyos-guides",multiplier:1.35},{pattern:/(如何|怎么|怎样|步骤)/,catalog:"harmonyos-guides",multiplier:1.45},{pattern:/(生命周期|原理|概述|什么是|模型|介绍)/,catalog:"harmonyos-guides",multiplier:1.35},{pattern:/(报错|失败|错误|异常|排查)/,catalog:"harmonyos-guides",multiplier:1.25},{pattern:/(报错|失败|FAQ)/i,catalog:"harmonyos-faqs",multiplier:1.2},{pattern:/(构建|签名|打包|发布|上架|应用市场|hvigor|ohpm)/i,catalog:"harmonyos-guides",multiplier:1.3},{pattern:/(行为变更|changelog|升级|适配|版本说明)/i,catalog:"harmonyos-releases",multiplier:1.3},{pattern:/(路由|弹窗|手势|页面|权限|装饰器)/,catalog:"harmonyos-guides",multiplier:1.25,skipForPureApiSymbol:!0}];function it(t,e,n){let r=R[e];t.set(r,(t.get(r)??1)*n)}function no(t,e){let n=t.trim(),r=/[\u4e00-\u9fff]/.test(n),o=/\b[A-Z][a-zA-Z0-9]{2,}\b/.test(n),i=/\b[a-z][a-zA-Z0-9]{3,}\b/.test(n);if(r&&(o||i)){it(e,"harmonyos-guides",1.45),it(e,"harmonyos-references",1.35);return}(o||i)&&it(e,"harmonyos-references",1.55),/\b[A-Z][a-zA-Z]*(Gesture|Dialog|Sheet|Transition|Recognizer)\b/.test(n)&&it(e,"harmonyos-references",1.75)}function Ln(t){let e=new Map,n=t.trim();if(!n)return e;let r=Tn(n);no(n,e),wn(n,e);for(let o of eo)o.pattern.test(n)&&(o.skipForPureApiSymbol&&r||it(e,o.catalog,o.multiplier));return e}import*as W from"fs";import*as jn from"path";var ro=[" ","\u3002","\uFF0C","\uFF1B","\u3001",".","!","?"];function Bn(t,e){let n=-1;for(let r of ro){let o=t.lastIndexOf(r);o>n&&(n=o)}return n>=e?n:-1}function Mn(t,e){let n=t.trim();if(n.length<=e)return{text:n,excerptTruncated:!1};let r=n.slice(0,e),o=Bn(r,e-20),i=o>=0?o:e;return{text:n.slice(0,i).trimEnd(),excerptTruncated:!0}}function kn(t,e,n={}){let{maxLen:r=Ze,contextChars:o=Ue,excerptTruncated:i=!1}=n,s=t.replace(/\s+/g," ").trim();if(!s)return"";if(s.length<=r)return i?`${s}...`:s;let a=e.split(/\s+/).map(Nt=>Nt.trim()).filter(Boolean),c=0;for(let Nt of a){let be=s.toLowerCase().indexOf(Nt.toLowerCase());if(be>=0){c=be;break}}let f=Math.max(0,c-o),p=Math.min(s.length,f+r),u=s.slice(f,p),E=Bn(u,r-25);E>=0&&(p=f+E);let h=s.slice(f,p).trim(),_=f>0?"...":"",fr=p<s.length||i?"...":"";return`${_}${h}${fr}`}var oo=`
3
- SELECT d.document_id, d.doc_title, s.section_title, s.lead_text, s.excerpt_truncated,
4
- d.catalog_id, bm25(segments_fts) AS bm25
5
- FROM segments_fts
6
- JOIN segments s ON s.id = segments_fts.rowid
7
- JOIN documents d ON d.id = s.doc_id
8
- WHERE segments_fts MATCH ?
9
- ORDER BY bm25(segments_fts)
10
- LIMIT ?
11
- `,io=`
12
- SELECT d.document_id, d.doc_title, s.section_title, s.lead_text, s.excerpt_truncated,
13
- d.catalog_id, bm25(segments_fts) AS bm25
14
- FROM segments_fts
15
- JOIN segments s ON s.id = segments_fts.rowid
16
- JOIN documents d ON d.id = s.doc_id
17
- WHERE segments_fts MATCH ? AND d.catalog_id = ?
18
- ORDER BY bm25(segments_fts)
19
- LIMIT ?
20
- `,so=3.5,ao=1.4,co=4,uo=1.8,lo=1.35,mo=3.5,fo=1.8,po=120,Fn=6;function de(t){return t.toLowerCase().replace(/[^\p{L}\p{N}@.]+/gu,"")}function go(t){return t.split(/[^\p{L}\p{N}@.]+/u).map(de).filter(e=>e.length>=2)}function ho(t,e){return e.length>1&&e.every(n=>t.includes(n))}function So(t){return/^[a-z0-9]{1,4}$/.test(t.trim().toLowerCase())}function yo(t,e){return t===e?mo:t.startsWith(e)||t.includes(`@ohos.${e}`)?fo:1}function xo(t,e){let n=de(e);if(n.length<2)return 1;let r=de(t.doc_title);if(So(e))return yo(r,n);if(r.includes(n))return co;if(n.length>=Fn&&r.includes(n.slice(0,Fn)))return uo;let o=go(e);return ho(r,o)?lo:1}function Eo(t,e){return e<=1?t:t<0?t*e:t/e}function Et(t,e,n,r){let o=t.bm25/(e.get(t.catalog_id)??1);return o=Eo(o,xo(t,n)),r&&ae(t.doc_title,t.section_title,r)&&(o/=so,t.catalog_id===R["harmonyos-references"]&&(o/=ao)),o}function le(t,e,n,r){return t.reduce((o,i)=>Et(i,e,n,r)<Et(o,e,n,r)?i:o)}function _o(t,e){return e.some(n=>t.section_title.includes(n)||t.doc_title.includes(n))}function bo(t,e,n,r,o){if(o){let i=t.filter(s=>ae(s.doc_title,s.section_title,o));if(i.length>0)return le(i,n,r,o)}if(e.length>0){let i=t.filter(s=>_o(s,e));if(i.length>0)return le(i,n,r,o)}return le(t,n,r,o)}function vn(t,e,n,r,o){let i=Ln(e),s=Dn(e),c=bn(e)?.camelCase,f=new Map;for(let h of t){let _=f.get(h.document_id)??[];_.push(h),f.set(h.document_id,_)}let p=[];for(let h of f.values())p.push(bo(h,s,i,n,c));let u=p.sort((h,_)=>Et(h,i,n,c)-Et(_,i,n,c));return(o?Pn(u):u).slice(0,r)}function _t(t,e,n,r,o,i){let s=e?R[e]:void 0,a=Math.max(n,n*Re,po),c=s===void 0?t.all(oo,r,a):t.all(io,r,s,a);return(s===void 0?vn(c,i,o,n,!0):vn(c,i,o,n,!1)).map(p=>({title:p.doc_title,documentId:p.document_id,sectionTitle:p.section_title||void 0,snippet:kn(p.lead_text,o,{excerptTruncated:!!p.excerpt_truncated})}))}var bt=`
21
- CREATE TABLE documents (
22
- id INTEGER PRIMARY KEY,
23
- document_id TEXT NOT NULL UNIQUE,
24
- catalog_id INTEGER NOT NULL,
25
- doc_title TEXT NOT NULL
26
- );
27
-
28
- CREATE TABLE segments (
29
- id INTEGER PRIMARY KEY,
30
- doc_id INTEGER NOT NULL REFERENCES documents(id),
31
- section_title TEXT NOT NULL DEFAULT '',
32
- lead_text TEXT NOT NULL DEFAULT '',
33
- search_text TEXT NOT NULL,
34
- excerpt_truncated INTEGER NOT NULL DEFAULT 0
35
- );
36
-
37
- CREATE VIRTUAL TABLE segments_fts USING fts5(
38
- search_text,
39
- content='segments',
40
- content_rowid='id',
41
- tokenize='unicode61'
42
- );
43
-
44
- CREATE TRIGGER segments_ai AFTER INSERT ON segments BEGIN
45
- INSERT INTO segments_fts(rowid, search_text) VALUES (new.id, new.search_text);
46
- END;
47
-
48
- CREATE TRIGGER segments_ad AFTER DELETE ON segments BEGIN
49
- INSERT INTO segments_fts(segments_fts, rowid, search_text) VALUES('delete', old.id, old.search_text);
50
- END;
51
-
52
- CREATE TRIGGER segments_au AFTER UPDATE ON segments BEGIN
53
- INSERT INTO segments_fts(segments_fts, rowid, search_text) VALUES('delete', old.id, old.search_text);
54
- INSERT INTO segments_fts(rowid, search_text) VALUES (new.id, new.search_text);
55
- END;
56
-
57
- CREATE INDEX segments_doc_id_idx ON segments(doc_id);
58
- `;var X=null,me=null;function Ao(){X?.close(),X=null,me=null}function Do(t,e){if(X&&me===e)return X;X?.close();let n=new t(e,{readonly:!0,fileMustExist:!0});return X=n,me=e,n.pragma("mmap_size = 268435456"),n.pragma("cache_size = -8000"),n.pragma("query_only = ON"),n}function Io(t,e){let n=new t(e);return n.pragma("journal_mode = OFF"),n.pragma("synchronous = OFF"),n.pragma("temp_store = MEMORY"),n.exec(bt),n}function To(t,e,n){let r=e.get(n.documentId);if(r!==void 0)return r;let i=t.prepare("SELECT id FROM documents WHERE document_id = ?").get(n.documentId);if(i)return e.set(n.documentId,i.id),i.id;let a=t.prepare(`
59
- INSERT INTO documents(document_id, catalog_id, doc_title)
60
- VALUES (?, ?, ?)
61
- `).run(n.documentId,n.catalogId,n.docTitle),c=Number(a.lastInsertRowid);return e.set(n.documentId,c),c}async function wo(t,e,n,r){await G();let o=Io(t,e),i=new Map,s=o.prepare(`
62
- INSERT INTO segments(doc_id, section_title, lead_text, search_text, excerpt_truncated)
63
- VALUES (?, ?, ?, ?, ?)
64
- `),a=n.length;for(let c=0;c<a;c+=v){let f=n.slice(c,c+v),p=await Promise.all(f.map(async E=>({source:E,searchText:await xt(E)})));o.transaction(E=>{for(let h of E){let _=To(o,i,h.source);s.run(_,h.source.sectionTitle,h.source.leadText,h.searchText,h.source.excerptTruncated?1:0)}})(p),await r?.(Math.min(c+f.length,a),a)}o.exec("ANALYZE"),o.exec("VACUUM"),o.close()}function Co(t,e,n,r,o,i,s){let a=Do(t,e);return _t({all(c,...f){return a.prepare(c).all(...f)}},n,r,o,i,s)}async function zn(){let e=(await import("better-sqlite3")).default;return{kind:"better-sqlite3",resetCache:Ao,buildSearchIndex:(n,r,o)=>wo(e,n,r,o),searchIndex:(n,r,o,i,s,a,c)=>Promise.resolve(Co(e,i,r,o,s,a,c))}}import{readFile as Ro,stat as No,writeFile as Oo}from"fs/promises";var fe=null,P=null;async function pe(){return fe||(fe=(async()=>{let t=(await import("@sqlite.org/sqlite-wasm")).default;return t()})()),fe}function Po(t){return{all(e,...n){let r=t.prepare(e);n.length>0&&r.bind(n);let o=[];for(;r.step();)o.push(r.get({}));return r.finalize(),o}}}async function Lo(t){let e=await No(t);if(P&&P.dbPath===t&&P.mtimeMs===e.mtimeMs)return P.db;P?.db.close();let n=await pe(),r=n.capi,o=n.wasm,i=new Uint8Array(await Ro(t)),s=o.allocFromTypedArray(i),a=new n.oo1.DB(":memory:"),c=r.SQLITE_DESERIALIZE_READONLY|r.SQLITE_DESERIALIZE_RESIZEABLE|r.SQLITE_DESERIALIZE_FREEONCLOSE;return r.sqlite3_deserialize(a.pointer,"main",s,i.byteLength,i.byteLength,c),P={dbPath:t,mtimeMs:e.mtimeMs,db:a},a}function Hn(){P?.db.close(),P=null}async function Bo(t,e,n,r){t.exec("BEGIN");for(let o of r){let i=n(o.source);e.bind([i,o.source.sectionTitle,o.source.leadText,o.searchText,o.source.excerptTruncated?1:0]),e.step(),e.reset()}t.exec("COMMIT")}function Mo(t,e,n){return r=>{let o=e.get(r.documentId);if(o!==void 0)return o;let i=t.selectValue("SELECT id FROM documents WHERE document_id = ?",[r.documentId]);if(i!=null){let a=Number(i);return e.set(r.documentId,a),a}n.bind([r.documentId,r.catalogId,r.docTitle]),n.step(),n.reset();let s=Number(t.selectValue("SELECT last_insert_rowid()"));return e.set(r.documentId,s),s}}async function ko(t,e,n){await G();let r=await pe(),o=new r.oo1.DB(":memory:","c");o.exec(bt);let i=new Map,s=o.prepare("INSERT INTO documents(document_id, catalog_id, doc_title) VALUES (?, ?, ?)"),a=o.prepare("INSERT INTO segments(doc_id, section_title, lead_text, search_text, excerpt_truncated) VALUES (?, ?, ?, ?, ?)"),c=Mo(o,i,s),f=e.length;for(let u=0;u<f;u+=v){let E=e.slice(u,u+v),h=await Promise.all(E.map(async _=>({source:_,searchText:await xt(_)})));await Bo(o,a,c,h),await n?.(Math.min(u+E.length,f),f)}o.exec("ANALYZE");let p=r.capi.sqlite3_js_db_export(o);await Oo(t,p),o.close(),Hn()}async function Fo(t,e,n,r,o,i){let s=await Lo(t);return _t(Po(s),e,n,r,o,i)}async function ge(){return await pe(),{kind:"sqlite-wasm",resetCache:Hn,buildSearchIndex:ko,searchIndex:(t,e,n,r,o,i,s)=>Fo(r,e,n,o,i,s)}}var At=null,he=null;function vo(){return W.existsSync(V())}function zo(t){let e=V(),n={backend:"sqlite-wasm",reason:"better-sqlite3-load-failed",message:t,createdAt:new Date().toISOString()};W.mkdirSync(jn.dirname(e),{recursive:!0}),nt(e),W.writeFileSync(e,JSON.stringify(n,null,2))}async function Ho(){if(vo())return ge();try{let t=await zn();return k("doc-index: using better-sqlite3 SQLite backend"),t}catch(t){let e=t instanceof Error?t.message:String(t);zo(e),k(`doc-index: better-sqlite3 unavailable (${e}); falling back to sqlite-wasm`)}return ge()}async function Se(){return At||(At=Ho().then(t=>(he=t,t))),At}function Zn(){he?.resetCache(),At=null,he=null}function Dt(){Zn()}async function Un(t,e,n){await(await Se()).buildSearchIndex(t,e,n)}import{unified as Yn}from"unified";import Vn from"remark-parse";import Kn from"remark-gfm";import{toString as Tt}from"mdast-util-to-string";var jo=/^(.+?)(\d+\+)?(对象|枚举|错误码)说明$/,Zo=/^\[h2\]([A-Za-z][A-Za-z0-9]*)(\d+\+)?$/,Uo=/^(.{2,20}?)\s*[((]([A-Za-z][a-zA-Z0-9]{1,40})[))]\s*$/,$o=/^([A-Za-z@][A-Za-z0-9@]*?)(\d+\+)?$/,Go=/^(系统能力|元服务API|参数|返回值|说明|\*\*|表格|\|)/;function It(t){let e=t.trim(),n=e.match($o);return n?n[1]:e}function Xo(t){let e=t.match(jo);if(!e)return;let n=It(e[1].trim());return{displayTitle:t,symbolName:n,searchExtras:[n,e[3]]}}function Wo(t){let e=It(t.replace(/\([^)]*\)$/,""));if(/^[A-Z][A-Za-z0-9]*$/.test(e))return{displayTitle:t,symbolName:e,searchExtras:[e]};if(/^[A-Z][A-Za-z0-9]*(\([^)]*\))?$/.test(t))return{displayTitle:t,symbolName:e,searchExtras:[e]}}function st(t){let e=t.trim();return e?Xo(e)??(()=>{let n=e.match(Zo);if(n){let r=n[1];return{displayTitle:e,symbolName:r,searchExtras:[r]}}})()??(()=>{let n=e.match(Uo);if(!n)return;let r=n[1].trim(),o=n[2].trim();return{displayTitle:e,symbolName:o,searchExtras:[r,o]}})()??Wo(e)??{displayTitle:e,searchExtras:[]}:{displayTitle:"",searchExtras:[]}}function Qo(t){if(t.length<2||t.length>36||Go.test(t))return!1;let e=[...t.replace(/\s/g,"")];return e.length===0?!1:e.filter(r=>new RegExp("\\p{Script=Han}","u").test(r)).length/e.length>=.4}function $n(t){for(let e of t){let n=e.trim().replace(/[。.!!??;;]+$/u,"").trim();if(Qo(n))return n}return""}function Gn(t,e,n){let r=[t,...n.searchExtras,e].filter(Boolean);return[...new Set(r)].join(" ")}var qo=/[A-Z][a-zA-Z0-9]+(?:\.[a-zA-Z][a-zA-Z0-9]+)*/g,at=/@[A-Z][a-zA-Z]+/g,Jo=/^[A-Z][A-Za-z0-9]*\.[A-Za-z][A-Za-z0-9]+/,Yo=/^[A-Z][A-Za-z0-9]+(?:\([^)]*\))?$/,Vo=/^[a-z0-9]+(?:[-_][a-z0-9]+)+$/,Ko=new Set(["API","Action","Code","Connect","Connection","Context","Direction","Element","Elements","Entry","Focused","Module","Modules","Name","Names","Stage","Type","Types","Value","Values","Rect","Error"]),ti=new Set(["HAP","HSP","HAR","NAPI","CAPI","NDK","ArkTS","ArkUI","OHPM"]),ei=new Set(["JSON","Object","Array","Promise","console","Math","Date","String","Number","Boolean","Error","Function","Map","Set","RegExp"]);function tr(t,e){let n=new Set,r=[t,...e];for(let o of r){for(let i of re(o)){A(n,i);let s=ht(i);s&&A(n,s)}for(let i of oe(o))A(n,i);for(let i of o.matchAll(qo)){let s=i[0];ni(s)&&n.add(s)}for(let i of o.matchAll(at))n.add(i[0])}return U([...n])}function ni(t){let e=t.trim();if(!e||at.test(e))return!!e;if(e.includes(".")){let n=e.split(".")[0]??"";return ei.has(n)?!1:/^[A-Z]/.test(n)}return Ko.has(e)?!1:ti.has(e)?!0:e.length<=3?!1:/^[A-Z][a-z]+[A-Z]/.test(e)?!0:e.length>=6&&/^[A-Z][A-Za-z0-9]+$/.test(e)}function Xn(t){let e=t.trim();return!!(!e||Vo.test(e)||e.length>28&&!/[A-Z\u4e00-\u9fff]/.test(e)&&/^[a-z0-9_-]+$/.test(e))}function er(t,e){let n=e.jsonTitle?.trim(),r=si(t,"").trim(),o=e.fileName.trim();return n&&!Xn(n)?n:r&&!Xn(r)?r:n||r||o}function nr(t){return Jo.test(t.trim())}function ye(t){let e=t.trim().replace(/\([^)]*\)$/,""),n=It(e);return Yo.test(n)}function wt(t){let e=t.trim();return e?at.test(e)||nr(e)||ye(e)?!0:!!st(e).symbolName:!1}function ri(t){let e=t.trim();return!(!e||nr(e)||ye(e))}function oi(t){let e=new Set,n=[];for(let r of t){let o=r.trim();!ri(o)||e.has(o)||(e.add(o),n.push(o))}return n}function Wn(t){if(!t.includes("."))return 0;let e=t.split(".").pop()??"";return/^[a-z]/.test(e)?1:2}function ii(t,e){let n=Wn(t)-Wn(e);return n!==0?n:t.localeCompare(e)}function rr(t,e=[]){let n=[...new Set(e.map(i=>i.trim()).filter(Boolean))],r=new Set(n),o=[...new Set(t.map(i=>i.trim()).filter(Boolean))].filter(i=>!r.has(i));return o.sort(ii),[...n,...o].slice(0,He)}function Ct(t){return t.replace(/\s+/g," ").trim()}function Qn(t){return t.replace(/\\([\\`*_{}[\]()#+.!-])/g,"$1")}function si(t,e=""){let n=t.split(/\r?\n/),r=0;for(;r<n.length&&!n[r].trim();)r+=1;if(r>=n.length)return e;let o=Qn(n[r].trim()),i=o.match(/^#+\s+(.+)$/);if(i)return Qn(i[1].trim());if(r+1<n.length){let s=n[r+1].trim();if(/^=+$/.test(s)||/^-+$/.test(s))return o}return o||e}function or(t){let e=Ct(t.join(" "));if(e.length<=ut)return e;let n=e.slice(0,ut);return e.length<=ut+Lt?n:`${n} ${e.slice(-Lt)}`}function ai(t){let e=oi(t).join(" ");return e.length<=Bt?e:e.slice(0,Bt)}function ir(t){let e=Ct(t),{text:n,excerptTruncated:r}=Mn(e,je);return{leadText:n,excerptTruncated:r}}function ci(t,e){let{leadText:n,excerptTruncated:r}=ir(t);return{leadText:n,excerptTruncated:r||!!e.trim()}}function sr(t,e){if(t.type==="code"){e.codeBlocks.push(t.value??"");return}if("children"in t&&Array.isArray(t.children)){for(let r of t.children)sr(r,e);return}let n=Ct(Tt(t));n&&e.bodyParts.push(n)}function ui(t){let e=Yn().use(Vn).use(Kn).parse(t),n=[],r=null,o=()=>{r&&((r.sectionTitle||r.bodyParts.length||r.codeBlocks.length)&&n.push(r),r=null)},i=()=>{r||(r={sectionTitle:"",bodyParts:[],codeBlocks:[]})};for(let s of e.children){if(s.type==="heading"){let a=s,c=Tt(a).trim();if(a.depth>=4&&c&&wt(c)){o(),r={sectionTitle:c,bodyParts:[],codeBlocks:[]};continue}i(),c&&r.bodyParts.push(c);continue}i(),sr(s,r)}return o(),n.length===0?[{sectionTitle:"",bodyParts:[],codeBlocks:[]}]:n}function li(t){return Ce.test(t)}function di(t){return t.filter(e=>e.sectionTitle&&wt(e.sectionTitle)).length}function mi(t){return{sectionTitle:t.map(e=>e.sectionTitle.trim()).join(" | "),bodyParts:t.flatMap(e=>e.bodyParts).slice(0,40),codeBlocks:t.flatMap(e=>e.codeBlocks).slice(0,8)}}function qn(t){let e=t.trim();return!e||at.test(e)?at.test(e):/对象说明$|枚举说明$/.test(e)?!0:ye(e)}function fi(t){let e=t.filter(u=>!u.sectionTitle||!wt(u.sectionTitle)),n=t.filter(u=>u.sectionTitle&&wt(u.sectionTitle)),r=n.filter(u=>qn(u.sectionTitle)),o=n.filter(u=>!qn(u.sectionTitle)),i=Math.max(0,we-r.length),s=o.slice(0,i),a=o.slice(i),c=a.filter(u=>Jn(u.sectionTitle)),f=a.filter(u=>!Jn(u.sectionTitle)),p=[];for(let u=0;u<f.length;u+=Pt)p.push(mi(f.slice(u,u+Pt)));return[...e,...r,...s,...c,...p]}function pi(t,e,n){let r=t.split(/\r?\n/).length,o=di(e);return o===0?!1:li(n)?r>=Ie&&o>=Te:r>=Ae&&o>=De}var gi=/^\[h2\][A-Za-z]/;function Jn(t){return gi.test(t.trim())}function ar(t){if(!t.includes(" | ")){let n=st(t);return n.symbolName?[n.symbolName]:[]}let e=[];for(let n of t.split(" | ")){let r=st(n.trim()).symbolName;r&&e.push(r)}return e}function hi(t,e,n,r){let o=ar(t),i=tr(n,r);return e.symbolName&&i.push(e.symbolName),rr([...o,...i],o)}function Si(t,e){let n=or(t.bodyParts),r=t.sectionTitle.trim(),o=st(r),i=$n(t.bodyParts),s=Gn(r,i,o),a=ar(r),c=r?a.length>0?`${e.docTitle} ${a.join(" ")}`:`${e.docTitle} ${o.symbolName??r}`:e.docTitle,f=[e.docTitle,s,...t.bodyParts].join(" "),{leadText:p,excerptTruncated:u}=ci(n,r);return{documentId:e.documentId,catalogId:e.catalogId,docTitle:e.docTitle,sectionTitle:r,titleTokens:c,headingsText:s,apiSymbols:hi(r,o,f,t.codeBlocks),bodySample:n,leadText:p,excerptTruncated:u}}function cr(t,e){for(let n of t){if(n.type==="heading"){let o=Tt(n).trim();o&&e.headings.push(o);continue}if(n.type==="code"){e.codeBlocks.push(n.value??"");continue}if("children"in n&&Array.isArray(n.children)){cr(n.children,e);continue}let r=Ct(Tt(n));r&&e.bodyParts.push(r)}}function yi(t){let e=Yn().use(Vn).use(Kn).parse(t),n={headings:[],bodyParts:[],codeBlocks:[]};return cr(e.children,n),n}function xi(t,e){let n=yi(t),r=e.docTitle?.trim()||e.documentId,o=or(n.bodyParts),i=[r,...n.headings,o].join(" "),{leadText:s,excerptTruncated:a}=ir(o);return{documentId:e.documentId,catalogId:e.catalogId,docTitle:r,sectionTitle:"",titleTokens:r,headingsText:ai(n.headings),apiSymbols:rr(tr(i,n.codeBlocks)),bodySample:o,leadText:s,excerptTruncated:a}}function ur(t,e){let n=e.docTitle?.trim()||e.documentId,r=ui(t);return pi(t,r,e.documentId)?fi(r).filter(o=>o.sectionTitle||o.bodyParts.length>0||o.codeBlocks.length>0).map(o=>Si(o,{...e,docTitle:n})):[xi(t,{...e,docTitle:n})]}async function _i(t,e,n){let r=Ee.join(e,"search.db");return await Un(r,t,async(o,i)=>{await n?.({current:o,total:i,message:`Building search index\u2026 ${o.toLocaleString()} / ${i.toLocaleString()} segments`})}),t.length}function bi(t){return t.getEntries().filter(e=>e.isDirectory||!e.entryName.endsWith(".md")?!1:e.entryName.split("/").every(r=>!r.startsWith(".")))}function Ai(t){let e=t.split("/");if(e[0]==="docs"&&(e=e.slice(1)),e.length<2)return null;let n=e[0],r=$e[n];if(r===void 0)return null;let o=e[e.length-1].replace(/\.md$/,"");return e[e.length-1]=o,{documentId:e.join("/"),catalogId:r,docTitle:o}}function Di(t,e){let n=e.replace(/\.md$/,".json"),r=t.getEntry(n);if(r)try{return JSON.parse(r.getData().toString("utf-8")).title?.trim()||void 0}catch{return}}function Ii(t,e){let n=Ai(t.entryName);if(!n)return[];let r=t.getData().toString("utf-8"),o=er(r,{jsonTitle:Di(e,t.entryName),fileName:n.docTitle});return ur(r,{...n,docTitle:o})}async function Ti(t){let e=new Ei(t),n=bi(e),r=[];for(let o of n){let i=Ii(o,e);r.push(...i)}return r}function wi(t,e){return{indexVersion:F,docsZipSha256:t.docsZipSha256,termsHash:t.termsHash,synonymsHash:t.synonymsHash,segmentCount:e,builtAt:Date.now(),builtBy:t.builtBy}}async function lr(t){t.lexiconDir&&Zt(t.lexiconDir);try{let e=await Ti(t.docsZipPath);await t.onProgress?.({current:0,total:e.length,message:`Building search index\u2026 0 / ${e.length.toLocaleString()} segments`}),await xe.promises.mkdir(t.tmpDir,{recursive:!0});let n=await _i(e,t.tmpDir,t.onProgress),r=wi(t,n);return await xe.promises.writeFile(Ee.join(t.tmpDir,"build-meta.json"),JSON.stringify(r,null,2)),await on(t.tmpDir),r}finally{t.lexiconDir&&Zt(null)}}async function mr(t){let e=vt();await x.promises.mkdir(Q.dirname(e),{recursive:!0}),await x.promises.appendFile(e,`${new Date().toISOString()} ${t}
65
- `)}async function Ni(){await rt({mode:"write"});let t=g(),e=I(),n=await x.promises.readdir(e);for(let r of n){let o=Q.join(t,r);await x.promises.rm(o,{force:!0}),await x.promises.rename(Q.join(e,r),o)}await x.promises.rm(e,{recursive:!0,force:!0}),await x.promises.rm(Q.join(t,"orama.dpack"),{force:!0})}async function dr(t,e,n){e?.start(n),await O({state:"installing",phase:1,phaseLabel:"Installing index",message:n}),await un(t),Dt(),e&&(e.text="Documentation index installed.")}async function Oi(t,e){try{return await dr(t,e,"Installing documentation index\u2026"),await _e(e),!0}catch(n){if(Wt(n))throw n}try{return await ln(),Dt(),await dr(t,e,"Retrying documentation index install\u2026"),await _e(e),!0}catch(n){if(Wt(n))throw n;let r=n instanceof Error?n.message:String(n);return await mr(`Bundled index install failed; falling back to local rebuild: ${r}`),!1}}async function Pi(t,e,n){let r=I(),o=B();if(!o)throw new Error("docs.zip not found");await x.promises.mkdir(g(),{recursive:!0}),await x.promises.rm(r,{recursive:!0,force:!0}),n?.start("Building search index\u2026"),await O({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"}),await lr({docsZipPath:o,tmpDir:r,docsZipSha256:e,termsHash:gt(),synonymsHash:pt(),builtBy:t.builtBy??"doc-init",onProgress:async i=>{n&&(n.text=i.message),await O({state:"indexing",current:i.current,total:i.total,message:i.message})}}),await O({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await Ni(),Dt()}async function _e(t){await O({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),t?.succeed("Documentation ready.")}async function Li(t){let e=await Vt(),n=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";t?.succeed(n),await O({state:"done",message:n,error:null})}async function Bi(t,e){let n=t instanceof Error?t.message:String(t);throw await O({state:"error",error:n}),await mr(`ERROR: ${n}`),e?.fail(n),t}async function Mi(){let t=g();await x.promises.mkdir(t,{recursive:!0});let e=lt();return x.existsSync(e)||await x.promises.writeFile(e,"","utf-8"),e}async function ki(){let t=await Mi();return Ci.lock(t,{stale:1800*1e3})}async function Fi(){let t=B(),e=(t?await ft(t):null)??await Yt();if(!e)throw new Error("docs.zip not found");return e}async function vi(t,e){let n=await Fi(),r=t.force||await Sn(t.force),o=await Kt(t.force);if(!r&&!o&&te()){await Li(e);return}!t.force&&cn(n)&&await Oi(n,e)||(await Pi(t,n,e),await _e(e))}var Rt=class{static async run(e={}){let n=e.background??!1,o=e.quiet??n?void 0:Ri({text:"Checking documentation\u2026",color:"cyan"}),i;try{e.assumeStorageSafe||await rt({mode:"write"}),i=await ki(),await Jt(hn("Starting documentation setup\u2026")),await vi(e,o)}catch(s){throw i&&await Bi(s,o),s}finally{i&&await i()}}};var zi=process.env.DEVECO_CLI_POSTINSTALL?"postinstall":"doc-init";Rt.run({background:!0,builtBy:zi}).then(()=>{process.exit(0)}).catch(()=>{process.exit(1)});
1
+ import*as L from"fs";import re from"proper-lockfile";import ne from"ora";import*as m from"fs";import*as b from"path";var G=["harmonyos-guides","harmonyos-references","best-practices","harmonyos-faqs","harmonyos-releases","harmonyos-roadmap"],O={"harmonyos-guides":"\u5F00\u53D1\u6307\u5357","harmonyos-references":"API\u53C2\u8003","best-practices":"\u6700\u4F73\u5B9E\u8DF5","harmonyos-faqs":"FAQ","harmonyos-releases":"\u7248\u672C\u8BF4\u660E","harmonyos-roadmap":"\u53D8\u66F4\u9884\u544A"};var N="1.9.1",ge=48*1024*1024;var he=Object.fromEntries(G.map((t,e)=>[O[t],e])),P=Object.fromEntries(G.map((t,e)=>[t,e]));import*as w from"fs";import*as a from"path";import{fileURLToPath as gt}from"url";import*as p from"fs";import*as mt from"path";import{homedir as Gt}from"os";import*as ut from"fs";import*as l from"path";function j(t,e){let r=l.relative(e,t);return r===""||!l.isAbsolute(r)&&!r.startsWith(`..${l.sep}`)&&r!==".."}function E(t){let e=l.resolve(t),r=[],n=e;for(;;)try{let o=ut.realpathSync(n);return r.length===0?o:l.join(o,...r.reverse())}catch(o){if(o.code!=="ENOENT")throw o;let u=l.dirname(n);if(u===n)return e;r.push(l.basename(n)),n=u}}function lt(t,e){let r=E(e),n=E(t);return j(n,r)?n:null}function Z(t){let e=t.trim();return(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))&&(e=e.slice(1,-1).trim()),e}function dt(t){let e=Z(t);if(!e)throw new Error("Path must not be empty.");return E(e)}var jt="deveco-cli",H,h=class extends Error{constructor(e){super(e),this.name="CliDataDirError"}};function pt(){let t=process.env.DEVECO_CLI_DATA_DIR,r=(t===void 0||t===""?"":Z(t))||mt.join(Gt(),".local","share",jt);try{return dt(r)}catch(n){throw new h(n instanceof Error?n.message:String(n))}}async function ft(){let t=pt();await p.promises.mkdir(t,{recursive:!0});let e;try{e=await p.promises.realpath(t)}catch(n){throw new h(`DEVECO_CLI_DATA_DIR is not usable: ${n instanceof Error?n.message:String(n)}`)}if(!(await p.promises.stat(e)).isDirectory())throw new h("DEVECO_CLI_DATA_DIR must be a writable directory.");return H=e,e}function M(){if(H!==void 0)return H;let t=pt();try{if(p.existsSync(t))return p.realpathSync(t)}catch{}return t}var Zt="docs";function Q(){return a.join(M(),Zt)}function c(){return a.join(Q(),".index")}function B(){return a.join(c(),"build.lock")}function T(){return a.join(c(),"build-status.json")}function _(){return a.join(c(),"build-meta.json")}function x(){return a.join(c(),"search.db")}function A(){return a.join(c(),".tmp")}function Ht(t,e){let r=e;for(;!r.endsWith(`${a.sep}dist`)&&r!==a.dirname(r);)r=a.dirname(r);return r}function ht(t,e){return a.dirname(Ht(t,e))}function St(){let t=gt(import.meta.url),e=a.dirname(t);return t.includes(`${a.sep}dist${a.sep}`)?ht(t,e):a.join(e,"..","..","..")}function Qt(...t){let e=gt(import.meta.url),r=a.dirname(e);return e.includes(`${a.sep}dist${a.sep}`)?[a.join(ht(e,r),...t)]:[a.join(r,"..","..","..",...t)]}function yt(...t){let e=St(),r=w.realpathSync(e);for(let n of Qt(...t))try{let o=w.lstatSync(n);if(o.isSymbolicLink()||!o.isFile())throw new Error(`Unsafe documentation package asset: ${t.join("/")} must be a regular file.`);let u=w.realpathSync(n);if(!j(u,r))throw new Error(`Unsafe documentation package asset: ${t.join("/")} is outside the package.`);return u}catch(o){if(o.code!=="ENOENT")throw o}return null}function C(){return yt("docs.zip")}function X(){return yt("index.zip")}function Et(){return a.join(St(),"index","data")}import*as S from"fs";import*as D from"path";var f=["harmonyos-terms.txt","harmonyos-synonyms.json","harmonyos-stopwords.txt"],W=class extends Error{constructor(e){super(e),this.name="LexiconNotFoundError"}};var _t=null;function Xt(){if(_t)return _t;let t=c();if(f.every(o=>S.existsSync(D.join(t,o))))return t;let r=Et();if(f.every(o=>S.existsSync(D.join(r,o))))return r;throw new W("Lexicon files not found. Install the documentation index first (index.zip).")}function $(t){let e=D.join(Xt(),t);return S.readFileSync(e,"utf-8")}function xt(t,e){return S.readFileSync(D.join(e,t),"utf-8")}import*as q from"fs";import*as Wt from"yauzl";function Y(){let t=C();return t!==null&&q.existsSync(t)}import*as d from"fs";import*as g from"path";import At from"adm-zip";import*as I from"fs";import*as v from"path";var F=class extends Error{constructor(e){super(`Unsafe documentation path: ${e}`),this.name="DocPathSafetyError"}};function K(t){return t instanceof h||t instanceof F||t instanceof Error&&(t.name==="CliDataDirError"||t.name==="DocPathSafetyError")}function tt(t){return new F(t)}function $t(){return E(M())}function J(t,e,r){let n=lt(t,e);if(n===null)throw tt(`${r} resolves outside the data directory.`);return n}async function V(t,e){await I.promises.mkdir(t,{recursive:!0});let r=J(t,e,"directory");if(!(await I.promises.stat(r)).isDirectory())throw tt("path must be a directory.")}function qt(t){let e=$t();try{let r=J(t,e,"file");if(!I.statSync(r).isFile())throw tt("path must be a regular file.")}catch(r){if(r.code==="ENOENT"){J(v.dirname(t),e,"file parent");return}throw r}}async function k(t={}){let e=t.mode??"write",r=await ft();await V(Q(),r),await V(c(),r),e==="write"&&await V(A(),r);for(let n of[x(),_(),T(),B(),...f.map(o=>v.join(c(),o))])qt(n)}var et=["search.db","build-meta.json",...f],Yt=["corpus.json","corpus-offsets.json","orama.dpack"];async function Vt(t){for(let e of Yt)await d.promises.rm(g.join(t,e),{force:!0})}function Ct(t){let r=new At(t).getEntry("build-meta.json");if(!r)throw new Error("index.zip is missing build-meta.json");return JSON.parse(r.getData().toString("utf-8"))}async function Jt(t){let e=c();await d.promises.mkdir(e,{recursive:!0});for(let r of et){let n=g.join(e,r);await d.promises.rm(n,{force:!0}),await d.promises.rename(g.join(t,r),n)}await Vt(e),await d.promises.rm(A(),{recursive:!0,force:!0})}function wt(t){let e=X();if(!e)return!1;try{let r=Ct(e);return r.indexVersion===N&&r.docsZipSha256===t&&r.segmentCount>0}catch{return!1}}async function Tt(t){await k({mode:"write"});let e=X();if(!e)throw new Error("index.zip not found");let r=Ct(e);if(r.docsZipSha256!==t)throw new Error("Bundled index.zip does not match docs.zip. Rebuild index.zip with npm run build:index.");if(r.segmentCount<=0)throw new Error("Bundled index.zip is empty");let n=A();await d.promises.rm(n,{recursive:!0,force:!0}),await d.promises.mkdir(n,{recursive:!0});let o=new At(e);for(let y of et){let ct=o.getEntry(y);if(!ct)throw new Error(`index.zip is missing ${y}`);await d.promises.writeFile(g.join(n,y),ct.getData())}let u=JSON.parse(await d.promises.readFile(g.join(n,"build-meta.json"),"utf-8"));if(!d.existsSync(g.join(n,"search.db")))throw new Error("index.zip is missing search.db");return await Jt(n),u}async function Dt(){await d.promises.rm(A(),{recursive:!0,force:!0});let t=c();for(let e of et)await d.promises.rm(g.join(t,e),{force:!0})}import{createHash as It}from"crypto";import*as bt from"fs";async function z(t){return new Promise((e,r)=>{let n=It("sha256"),o=bt.createReadStream(t);o.on("data",u=>n.update(u)),o.on("error",r),o.on("end",()=>e(n.digest("hex")))})}function Rt(t){return It("sha256").update(t,"utf8").digest("hex")}function Lt(t,e){let r=e?xt(t,e):$(t);return Rt(r)}function Ot(t){return Lt("harmonyos-synonyms.json",t)}function Nt(t){return Lt("harmonyos-terms.txt",t)}var Kt={state:"idle",phase:0,phaseLabel:"Idle",current:0,total:0,message:"",startedAt:0,updatedAt:0,error:null};async function Pt(){try{let t=await m.promises.readFile(T(),"utf-8");return JSON.parse(t)}catch{return{...Kt}}}async function rt(t){let e=T();await m.promises.mkdir(b.dirname(e),{recursive:!0}),await m.promises.writeFile(e,JSON.stringify(t,null,2))}function Mt(t){let e=Date.now();return{state:"installing",phase:1,phaseLabel:"Preparing documentation index",current:0,total:0,message:t,startedAt:e,updatedAt:e,error:null}}async function R(t){let r={...await Pt(),...t,updatedAt:Date.now()};return await rt(r),r}async function nt(){let t=C();return t?z(t):null}async function ot(){try{let t=await m.promises.readFile(_(),"utf-8");return JSON.parse(t)}catch{return null}}async function it(t=!1){if(t)return"no-index";let e=await ot();if(!e||e.segmentCount===0)return"no-index";let r=await nt();return r&&e.docsZipSha256!==r?"docs-changed":e.indexVersion!==N?"engine-upgraded":e.termsHash!==Nt()?"terms-changed":e.synonymsHash!==Ot()?"synonyms-changed":null}function st(){if(!Y()||!m.existsSync(x())||!m.existsSync(_()))return!1;let t=b.dirname(x());if(!f.every(e=>m.existsSync(b.join(t,e))))return!1;try{let e=m.readFileSync(_(),"utf-8");return JSON.parse(e).segmentCount>0}catch{return!1}}async function Bt(t=!1){return t?!0:Y()?st()?await it()!==null:!0:!1}import{createRequire as te}from"module";var Wr=te(import.meta.url);var Ft=["harmonyos-releases","harmonyos-roadmap"],wn=new Set(Ft.map(t=>P[t])),Tn=Ft.map(t=>`${O[t]}/`);var oo=Promise.resolve();var ee=null,vt=null;function kt(){vt?.resetCache(),ee=null,vt=null}function at(){kt()}async function zt(t,e,r){e?.start(r),await R({state:"installing",phase:1,phaseLabel:"Installing index",message:r}),await Tt(t),at(),e&&(e.text="Documentation index installed.")}async function oe(t,e){try{return await zt(t,e,"Installing documentation index\u2026"),await Ut(e),!0}catch(r){if(K(r))throw r}try{return await Dt(),at(),await zt(t,e,"Retrying documentation index install\u2026"),await Ut(e),!0}catch(r){if(K(r))throw r;return!1}}async function Ut(t){await R({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),t?.succeed("Documentation ready.")}async function ie(t){let e=await ot(),r=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";t?.succeed(r),await R({state:"done",message:r,error:null})}async function se(t,e){let r=t instanceof Error?t.message:String(t);throw await R({state:"error",error:r}),e?.fail(r),t}async function ae(){let t=c();await L.promises.mkdir(t,{recursive:!0});let e=B();return L.existsSync(e)||await L.promises.writeFile(e,"","utf-8"),e}async function ce(){let t=await ae();return re.lock(t,{stale:1800*1e3})}async function ue(){let t=C(),e=(t?await z(t):null)??await nt();if(!e)throw new Error("docs.zip not found");return e}async function le(t,e){let r=await ue(),n=t.force||await Bt(t.force),o=await it(t.force);if(!n&&!o&&st()){await ie(e);return}if(!(wt(r)&&await oe(r,e)))throw new Error("Documentation index bundle is unavailable or corrupted. Reinstall the package with: npm uninstall -g @deveco/deveco-cli && npm install -g <package.tgz>")}var U=class{static async run(e={}){let r=e.background??!1,o=e.quiet??r?void 0:ne({text:"Checking documentation\u2026",color:"cyan"}),u;try{e.assumeStorageSafe||await k({mode:"write"}),u=await ce(),await rt(Mt("Starting documentation setup\u2026")),await le(e,o)}catch(y){throw u&&await se(y,o),y}finally{u&&await u()}}};var de=process.env.DEVECO_CLI_POSTINSTALL?"postinstall":"doc-init";U.run({background:!0,builtBy:de}).then(()=>{process.exit(0)}).catch(()=>{process.exit(1)});
@@ -0,0 +1,9 @@
1
+ import At from"path";import*as S from"fs";import*as K from"path";import{homedir as pt}from"os";import*as V from"fs";import*as d from"path";function P(r){let t=d.resolve(r),e=[],n=t;for(;;)try{let i=V.realpathSync(n);return e.length===0?i:d.join(i,...e.reverse())}catch(i){if(i.code!=="ENOENT")throw i;let o=d.dirname(n);if(o===n)return t;e.push(d.basename(n)),n=o}}function R(r){let t=r.trim();return(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1).trim()),t}function z(r){let t=R(r);if(!t)throw new Error("Path must not be empty.");return P(t)}var ft="deveco-cli",H,$=class extends Error{constructor(t){super(t),this.name="CliDataDirError"}};function dt(){let r=process.env.DEVECO_CLI_DATA_DIR,e=(r===void 0||r===""?"":R(r))||K.join(pt(),".local","share",ft);try{return z(e)}catch(n){throw new $(n instanceof Error?n.message:String(n))}}function J(){if(H!==void 0)return H;let r=dt();try{if(S.existsSync(r))return S.realpathSync(r)}catch{}return r}import ut from"crypto";import g from"fs";import U from"os";import v from"path";import vt from"https";var W={devecoApiTraceUpload:"https://cn.devecostudio.huawei.com/codeGenie/cli/trace/upload"};import*as c from"fs";import*as L from"path";import*as x from"os";import*as h from"path";import qt from"json5";function Y(){if(process.platform==="win32"){let r=process.env.LOCALAPPDATA??h.join(x.homedir(),"AppData","Local");return h.join(r,"devecocli-mcp-server","logs")}return process.platform==="darwin"?h.join(x.homedir(),"Library","Logs","devecocli-mcp-server"):h.join(x.homedir(),".local","share","devecocli-mcp-server","logs")}var q="mcp-server.log",mt="mcp-server",ht={maxSize:10*1024*1024,maxFiles:4},N=class r{fd=null;logDir=null;currentLogFile=null;mode;rotationOptions;currentFileSize=0;currentDate="";isRotating=!1;minLevel;static LEVEL_ORDER={debug:0,info:1,warn:2,error:3};constructor(t,e){this.rotationOptions={...ht,...e},this.minLevel=t?"debug":"info",t?(this.mode="console",this.logDir=null,this.currentLogFile=null):(this.mode="file",this.logDir=Y(),this.currentLogFile=L.join(this.logDir,q),c.existsSync(this.logDir)||c.mkdirSync(this.logDir,{recursive:!0}),this.cleanupOrphanLogFiles(),this.openLogFile())}getCurrentDateString(){let t=new Date,e=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${e}-${n}-${i}`}getRotatedFileName(t,e){return L.join(this.logDir,`${mt}-${t}.log.${e}`)}fileExists(t){try{return c.accessSync(t,c.constants.F_OK),!0}catch{return!1}}cleanupOrphanLogFiles(){if(this.logDir)try{let t=c.readdirSync(this.logDir),e=[];for(let i of t)if(i===q||/^mcp-server-\d{4}-\d{2}-\d{2}\.log\.\d+$/.test(i)){let o=L.join(this.logDir,i),a=c.statSync(o);e.push({name:i,mtime:a.mtime,path:o})}e.sort((i,o)=>o.mtime.getTime()-i.mtime.getTime());let n=1+this.rotationOptions.maxFiles;for(let i=n;i<e.length;i++)try{c.unlinkSync(e[i].path)}catch{}}catch{}}rotateLog(){if(!(this.isRotating||!this.logDir||!this.currentLogFile)){this.isRotating=!0;try{if(this.closeLogFile(),!this.fileExists(this.currentLogFile)){this.isRotating=!1,this.openLogFile();return}let t=this.getCurrentDateString(),e=this.getRotatedFileName(t,this.rotationOptions.maxFiles);this.fileExists(e)&&c.unlinkSync(e);for(let i=this.rotationOptions.maxFiles-1;i>=1;i--){let o=this.getRotatedFileName(t,i),a=this.getRotatedFileName(t,i+1);this.fileExists(o)&&c.renameSync(o,a)}let n=this.getRotatedFileName(t,1);c.renameSync(this.currentLogFile,n),this.cleanupOrphanLogFiles(),this.openLogFile()}catch{this.openLogFile()}finally{this.isRotating=!1}}}openLogFile(){if(this.currentLogFile){this.currentDate=this.getCurrentDateString();try{if(this.fileExists(this.currentLogFile)){let t=c.statSync(this.currentLogFile);this.currentFileSize=t.size}else this.currentFileSize=0}catch{this.currentFileSize=0}try{this.fd=c.openSync(this.currentLogFile,"a")}catch{this.fd=null}}}closeLogFile(){if(this.fd!==null){try{c.closeSync(this.fd)}catch{}this.fd=null}}checkRotation(t){let e=this.getCurrentDateString();this.currentDate&&this.currentDate!==e&&(this.rotateLog(),this.currentDate=e),this.currentFileSize+=t,this.currentFileSize>=this.rotationOptions.maxSize&&this.rotateLog()}write(t,e,...n){if(this.mode==="silent"||r.LEVEL_ORDER[t]<r.LEVEL_ORDER[this.minLevel])return;let i=n.map(l=>l instanceof Error?`${l.name}: ${l.message}`:typeof l=="object"?JSON.stringify(l,null,2):String(l)).join(" "),o=i?`${e} ${i}`:e,f=`[${new Date().toLocaleString("sv-SE",{timeZone:"Asia/Shanghai",hour12:!1})+"."+String(new Date().getMilliseconds()).padStart(3,"0")}] [MCP/${t.toUpperCase()}] ${o}
2
+ `;if(this.mode==="file"&&this.currentLogFile){if(this.fd===null&&this.openLogFile(),this.fd!==null)try{let l=Buffer.from(f);c.writeSync(this.fd,l),this.checkRotation(l.byteLength)}catch{this.closeLogFile(),this.openLogFile()}}else this.mode==="console"&&process.stderr.write(f)}debug(t,...e){this.write("debug",t,...e)}info(t,...e){this.write("info",t,...e)}warn(t,...e){this.write("warn",t,...e)}error(t,...e){this.write("error",t,...e)}dispose(){this.closeLogFile()}flush(){if(!(this.mode!=="file"||this.fd===null))try{c.fsyncSync(this.fd)}catch{}}getLogFilePath(){return this.currentLogFile}getLogDirectory(){return this.logDir}},E=null;function yt(r=!1){E&&E.dispose(),E=new N(r)}function C(){return E||yt(!1),E}var s={debug:(r,...t)=>C().debug(r,...t),info:(r,...t)=>C().info(r,...t),warn:(r,...t)=>C().warn(r,...t),error:(r,...t)=>C().error(r,...t)};var _=class r{static DEBUG=!0;static ENDPOINT=W.devecoApiTraceUpload;static SENDER="deveco-cli";async upload(t,e){let n={"Content-Type":"application/json",sender:r.SENDER,deviceid:e.replace(/-/g,""),"Content-Length":String(Buffer.byteLength(t,"utf8"))};r.log(`upload request: URL=${r.ENDPOINT}`);try{let{code:i,body:o}=await this.httpPost(r.ENDPOINT,n,Buffer.from(t,"utf8"),6e4);return r.log(`upload response: status=${i}, body=${o}`),r.isSuccess(o)}catch(i){return r.log(`upload failed: ${i instanceof Error?i.message:String(i)}`),!1}}static isSuccess(t){try{let e=JSON.parse(t),n=e?.code??e?.errorCode;return String(n)==="200"}catch{return!1}}async httpPost(t,e,n,i){let o=new URL(t);return new Promise((a,f)=>{let l=vt.request({protocol:o.protocol,hostname:o.hostname,port:o.port||(o.protocol==="https:"?443:80),path:o.pathname+o.search,method:"POST",headers:e,timeout:i},y=>{let m=[];y.on("data",D=>m.push(D)),y.on("end",()=>{a({code:y.statusCode??0,body:Buffer.concat(m).toString("utf8")})})});l.on("timeout",()=>{l.destroy(new Error("request timeout"))}),l.on("error",f),l.write(n),l.end()})}static log(t){r.DEBUG&&s.info("[TRACE]"+t)}};var X={identity:r=>r,camelCase:r=>r,snakeCase:r=>r.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase()},M=class{constructor(t={}){this.config=t}serialize(t){let e=this.transform(t);return this.config.pretty?JSON.stringify(e,null,2):JSON.stringify(e)}toObject(t){return this.transform(t)}transform(t){if(t==null)return t;if(Array.isArray(t))return t.map(o=>this.transform(o));if(typeof t!="object")return t;let e=this.config.namingStrategy??X.identity,n=this.config.fieldNames??{},i={};for(let[o,a]of Object.entries(t)){let f=n[o]??e(o);i[f]=this.transform(a)}return i}},G=new M({namingStrategy:X.snakeCase,fieldNames:{}});import b from"crypto";import k from"fs";import St from"path";var F="aes-256-gcm",xt=12,Et="deveco-cli-trace-file",bt="trace-file-secret",Q=32;function Z(r){try{let t=k.readFileSync(r,"utf8").trim();return t&&Buffer.from(t,"base64").length===Q?t:null}catch{return null}}function tt(r){let t=St.join(r,bt),e=Z(t);if(e)return j(e);let n=b.randomBytes(Q).toString("base64");try{k.mkdirSync(r,{recursive:!0});try{k.writeFileSync(t,n,{flag:"wx"})}catch{let i=Z(t);if(i)return j(i);k.writeFileSync(t,n)}}catch{}return j(n)}function j(r){return b.createHash("sha256").update(Et).update(r).digest()}function B(r,t){let e=b.randomBytes(xt),n=b.createCipheriv(F,t,e),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o={version:1,algorithm:F,ciphertext:i.toString("base64"),iv:e.toString("base64"),authTag:n.getAuthTag().toString("base64")};return JSON.stringify(o)}function et(r,t){let e;try{e=JSON.parse(r)}catch{return null}if(!Tt(e))return r;try{let n=b.createDecipheriv(F,t,Buffer.from(e.iv,"base64"));return n.setAuthTag(Buffer.from(e.authTag,"base64")),Buffer.concat([n.update(Buffer.from(e.ciphertext,"base64")),n.final()]).toString("utf8")}catch{return null}}function Tt(r){if(!r||typeof r!="object")return!1;let t=r;return t.version===1&&t.algorithm===F&&typeof t.ciphertext=="string"&&typeof t.iv=="string"&&typeof t.authTag=="string"}import rt from"fs";import wt from"path";var T=300*1e3;function O(){let r=process.env.DEVECO_CLI_DISABLE_TELEMETRY;return r==="1"||r==="true"}var Dt="upload-state.json";function nt(r){return wt.join(r,Dt)}function Ct(){return{firstEventAt:null,lastUploadAt:null}}function it(r){try{let t=rt.readFileSync(nt(r),"utf8"),e=JSON.parse(t);return{firstEventAt:typeof e.firstEventAt=="number"?e.firstEventAt:null,lastUploadAt:typeof e.lastUploadAt=="number"?e.lastUploadAt:null}}catch{return Ct()}}function ot(r,t){try{rt.writeFileSync(nt(r),JSON.stringify(t),"utf8")}catch{}}function st(r){let t=it(r);t.firstEventAt===null&&(t.firstEventAt=Date.now(),ot(r,t))}function at(r){let t=it(r);t.lastUploadAt=Date.now(),t.firstEventAt=null,ot(r,t)}import Lt from"crypto";import A from"fs";import _t from"path";var kt="install-id";function Ft(r){return _t.join(r,kt)}function ct(r){try{let t=A.readFileSync(r,"utf8").trim();return Ot(t)?t:null}catch{return null}}function Ot(r){return/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(r)}function lt(r){let t=Ft(r),e=ct(t);if(e)return e;let n=Lt.randomUUID();try{A.mkdirSync(r,{recursive:!0});try{A.writeFileSync(t,n,{flag:"wx"})}catch{let i=ct(t);if(i)return i;A.writeFileSync(t,n)}}catch{}return n}var w=class r{static MAX_BATCH=200;static MAX_PAYLOAD_BYTES=Math.floor(1.7*1024*1024);static TRACE_OS_VERSION="1.0";static COUNTRY_CODE="CN";static EVENT_PREFIX="devecocli_";uploader=new _;storageDir="";failedDir="";installId="";disabled=O();traceFileKey=Buffer.alloc(0);sessionId=ut.randomUUID();cliVersion="";devecoStudioVersion=null;sourceType="";cltVersion=null;nodeVersion="";initialTimer=null;intervalTimer=null;constructor(){s.info(`[telemetry] instance created, sessionId=${this.sessionId}`)}init(t){this.storageDir=t,this.failedDir=v.join(t,"failed"),this.cliVersion="1.3.1-Test.2",this.nodeVersion=process.version,this.installId=lt(t).replace(/-/g,""),this.traceFileKey=tt(t),g.mkdirSync(t,{recursive:!0}),g.mkdirSync(this.failedDir,{recursive:!0}),s.info(`[telemetry] init: dir=${t}, failedDir=${this.failedDir}, cliVersion=${this.cliVersion}, os=${this.resolveOsName()}, arch=${this.resolveOsArch()}, node=${this.nodeVersion}`)}setStudioVersion(t){this.devecoStudioVersion=t,s.info(`[telemetry] studio version set: ${t}`)}setSourceType(t){this.sourceType=t,s.info(`[telemetry] sourceType set: ${t}`)}setCltVersion(t){this.cltVersion=t,s.info(`[telemetry] CLT version set: ${t}`)}async track(t,e){if(this.disabled)return typeof e=="function"?e():void 0;if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");if(s.info(`[telemetry] track: ${t.event}`),!e){await this.record(t,0,!0,null),s.info(`[telemetry] track recorded: ${t.event} (no measurement)`);return}if(typeof e!="function"){let o=e;await this.record(t,o.duration_ms,o.success,o.error_code),s.info(`[telemetry] track recorded: ${t.event} (measurement: duration=${o.duration_ms}ms, success=${o.success}, code=${o.error_code})`);return}let n=e,i=Date.now();try{let o=await n(),a=Date.now()-i;return await this.record(t,a,!0,null),s.info(`[telemetry] track success: ${t.event}, duration=${a}ms`),o}catch(o){let a=Date.now()-i,f=this.toErrorCode(o);throw await this.record(t,a,!1,f),s.info(`[telemetry] track failed: ${t.event}, duration=${a}ms, code=${f}`),o}}async record(t,e,n,i){let o=this.buildTraceEvent(t,e,n,i);try{let a=B(JSON.stringify(o),this.traceFileKey);await g.promises.appendFile(this.currentFile(),a+`
3
+ `,"utf8"),s.info(`[telemetry] event persisted: ${o.properties.trace_uuid}`),st(this.storageDir)}catch(a){s.error("[telemetry] track write error:",a)}}buildTraceEvent(t,e,n,i){let o=`${r.EVENT_PREFIX}${t.event}`,a=G.toObject(t);return a&&typeof a=="object"&&delete a.event,{countryCode:r.COUNTRY_CODE,event:o,eventtime:String(Date.now()),properties:{uid:this.installId,trace_uuid:ut.randomUUID(),trace_os_version:r.TRACE_OS_VERSION,os_arch:this.resolveOsArch(),action:o,trace_os_name:this.resolveOsName(),version:`${this.cliVersion}_${this.resolveOsSuffix()}`,deveco_studio_version:this.formatVersion(this.devecoStudioVersion),command_line_version:this.formatVersion(this.cltVersion),source_type:this.sourceType,session_id:this.sessionId,node_version:this.nodeVersion,duration_ms:e,success:n,error_code:i,event_detail:a}}}toErrorCode(t){return t instanceof Error?t.code??t.name:"UnknownError"}resolveOsArch(){let t=U.arch();return t==="x64"?"amd64":t}resolveOsName(){switch(process.platform){case"win32":{let t=U.release().split(".");return(parseInt(t[t.length-1],10)||0)>=22e3?"Windows 11":"Windows 10"}case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}resolveOsSuffix(){switch(process.platform){case"win32":return"windows";case"darwin":return U.arch()==="arm64"?"mac_arm":"mac";default:return"linux"}}formatVersion(t){return t?`${t}_${this.resolveOsSuffix()}`:""}dateString(){let t=new Date,e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${t.getFullYear()}-${e}-${n}`}currentFile(){return v.join(this.storageDir,`telemetry-${this.dateString()}.txt`)}startScheduler(){if(this.stopScheduler(),this.disabled){s.info("[telemetry] scheduler not started (telemetry disabled)");return}s.info(`[telemetry] scheduler started (first flush in ${T/1e3}s, then every ${T/1e3}s)`),this.initialTimer=setTimeout(()=>{this.flush().catch(t=>s.error("[telemetry] flush error:",t)),this.intervalTimer=setInterval(()=>{this.flush().catch(t=>s.error("[telemetry] flush error:",t))},T)},T)}stopScheduler(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.intervalTimer&&(clearInterval(this.intervalTimer),this.intervalTimer=null),s.info("[telemetry] scheduler stopped")}async flush(){if(this.disabled)return!0;if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");s.info("[telemetry] flush start");let t=await this.listPendingFiles();if(t.length===0)return s.info("[telemetry] flush: no event files"),!0;s.info(`[telemetry] flush: ${t.length} file(s) pending`);let e=!0;for(let n of t)await this.flushFile(n)||(e=!1);return s.info(`[telemetry] flush done, allOk=${e}`),at(this.storageDir),e}async listPendingFiles(){let t;try{t=await g.promises.readdir(this.storageDir)}catch{return[]}return t.filter(e=>e.startsWith("telemetry-")&&e.endsWith(".txt")).map(e=>v.join(this.storageDir,e)).sort()}async flushFile(t){let e=t+".pending";try{await g.promises.rename(t,e),s.info(`[telemetry] flush: renamed ${v.basename(t)} \u2192 pending`)}catch{return!1}let n;try{n=await g.promises.readFile(e,"utf8")}catch{return!1}let i=n.split(`
4
+ `).map(f=>f.trim()).filter(Boolean),o=[],a=0;for(let f of i){let l=et(f,this.traceFileKey);if(l===null){a++;continue}o.push(l)}if(a>0&&s.warn(`[telemetry] flush: skipped ${a} undecryptable line(s)`),o.length===0){try{await g.promises.unlink(e)}catch{}return!0}return this.uploadInBatches(e,o)}async uploadInBatches(t,e){let n=0;for(;n<e.length;){let i=n,o=[],a=16;for(;n<e.length&&o.length<r.MAX_BATCH;){let m=e[n],D=Buffer.byteLength(m,"utf8")+1;if(o.length>0&&a+D>r.MAX_PAYLOAD_BYTES)break;o.push(m),a+=D,n++}let f=this.buildPayloadItems(o),l=JSON.stringify(f);s.info(`[telemetry] flush: uploading batch (${f.length} events, ${Buffer.byteLength(l,"utf8")} bytes)`);let y=!1;try{y=await this.uploader.upload(l,this.installId)}catch(m){s.error("[telemetry] build/upload error:",m)}if(!y){let m=e.slice(i).join(`
5
+ `)+`
6
+ `;return await this.moveToFailed(t,m),!1}}try{await g.promises.unlink(t)}catch{}return s.info("[telemetry] flush: file done, pending removed"),!0}buildPayloadItems(t){let e=[];for(let n of t)try{let i=JSON.parse(n);e.push({action:i.event,detail:JSON.stringify(i.properties),timestamp:Number(i.eventtime)||Date.now()})}catch{}return e}async moveToFailed(t,e){let n=v.basename(t,".pending"),i=v.join(this.failedDir,n);s.info(`[telemetry] moving to failed: ${n}`);try{let o=e.split(`
7
+ `).filter(Boolean).map(a=>B(a,this.traceFileKey)).join(`
8
+ `)+`
9
+ `;await g.promises.appendFile(i,o,"utf8")}catch(o){s.error("[telemetry] move to failed error:",o);return}try{await g.promises.unlink(t)}catch{}}};var I=new w;import{spawn as Ue}from"child_process";import{existsSync as ze}from"fs";import{dirname as Ke,join as Je}from"path";import{fileURLToPath as Ye}from"url";var It=At.join(J(),"TraceLogData");I.init(It);I.flush().then(r=>{r?s.info("[telemetry] background upload completed"):s.warn("[telemetry] background upload completed with failures")}).catch(r=>{s.error("[telemetry] background upload error:",r),process.exit(1)});
package/docs.zip CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/docs.zip
3
- size: 38105344 bytes
4
- sha256: 52fddd08cff9ece501454f82ee365632077cfbc9da4a4f6a4f5f30b58b65f79b
3
+ size: 40538363 bytes
4
+ sha256: 69cea82c1729991ed37837dc115cb43463b45b6381de6005f9d0c153399f6d1f
package/index.zip CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deveco-test/deveco-cli",
3
- "version": "1.3.0-Test.9",
3
+ "version": "1.3.1-Test.2",
4
4
  "description": "HarmonyOS application development command line tool",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,12 +10,6 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "scripts/postinstall.mjs",
13
- "scripts/install-better-sqlite3.mjs",
14
- "scripts/install-jieba-wasm.mjs",
15
- "scripts/lib/better-sqlite3-vendor.mjs",
16
- "scripts/lib/jieba-wasm-vendor.mjs",
17
- "scripts/lib/cli-data-dir.mjs",
18
- "scripts/lib/doc-init-log-path.mjs",
19
13
  "templates",
20
14
  "src/resources",
21
15
  "THIRD-PARTY-LICENSES",
@@ -30,6 +24,9 @@
30
24
  "build:index": "tsx index/build-index-bundle.ts",
31
25
  "dev": "tsx watch src/cli.ts",
32
26
  "start": "tsx src/cli.ts",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "test:coverage": "vitest run --coverage",
33
30
  "lint": "eslint src",
34
31
  "lint:fix": "eslint src --fix",
35
32
  "format": "prettier --write src",
@@ -37,7 +34,7 @@
37
34
  "prepublishOnly": "npm run lint && npm run license && npm run build"
38
35
  },
39
36
  "engines": {
40
- "node": ">=18"
37
+ "node": ">=22"
41
38
  },
42
39
  "keywords": [
43
40
  "harmonyos",
@@ -47,7 +44,6 @@
47
44
  "devDependencies": {
48
45
  "@eslint/js": "^10.0.1",
49
46
  "@types/adm-zip": "^0.5.8",
50
- "@types/better-sqlite3": "^7.6.13",
51
47
  "@types/fs-extra": "^11.0.4",
52
48
  "@types/global-agent": "^3.0.0",
53
49
  "@types/node": "^25.6.0",
@@ -64,19 +60,20 @@
64
60
  "tsx": "^4.21.0",
65
61
  "turndown": "^7.2.4",
66
62
  "typescript": "^6.0.3",
67
- "typescript-eslint": "^8.59.1"
63
+ "typescript-eslint": "^8.59.1",
64
+ "vitest": "^4.1.10"
68
65
  },
69
66
  "dependencies": {
70
67
  "@modelcontextprotocol/sdk": "^1.29.0",
71
- "@node-rs/jieba": "^2.0.1",
72
- "@sqlite.org/sqlite-wasm": "^3.49.1-build4",
73
- "adm-zip": "^0.5.17",
74
- "axios": "1.17.0",
68
+ "@sqlite.org/sqlite-wasm": "3.54.1-build1",
69
+ "adm-zip": "0.6.1",
70
+ "axios": "1.20.0",
75
71
  "colorette": "^2.0.20",
76
72
  "commander": "^13.1.0",
77
73
  "execa": "^9.6.1",
78
74
  "fs-extra": "^11.3.4",
79
75
  "global-agent": "^4.1.3",
76
+ "jieba-wasm": "^2.4.0",
80
77
  "json5": "^2.2.3",
81
78
  "mdast-util-to-string": "^4.0.0",
82
79
  "node-forge": "^1.4.0",
@@ -88,14 +85,11 @@
88
85
  "remark-parse": "^11.0.0",
89
86
  "semver": "^7.8.5",
90
87
  "smol-toml": "^1.6.1",
88
+ "socket.io-client": "^4.7.5",
91
89
  "unified": "^11.0.5",
92
90
  "yauzl": "^3.2.0",
93
91
  "zod": "^4.4.3"
94
92
  },
95
- "optionalDependencies": {
96
- "@node-rs/jieba-wasm32-wasi": "2.0.1",
97
- "better-sqlite3": "^12.11.1"
98
- },
99
93
  "overrides": {
100
94
  "dotenv": "16.4.7"
101
95
  }
@@ -4,32 +4,11 @@
4
4
  */
5
5
 
6
6
  import { spawn } from 'child_process';
7
- import { existsSync, mkdirSync } from 'fs';
7
+ import { existsSync } from 'fs';
8
8
  import { dirname, join } from 'path';
9
9
  import { fileURLToPath } from 'url';
10
- import { ensureBetterSqlite3ForDocs } from './install-better-sqlite3.mjs';
11
- import { ensureJiebaWasmForDocs } from './install-jieba-wasm.mjs';
12
- import { getDocInitLogPath } from './lib/doc-init-log-path.mjs';
13
10
 
14
11
  const root = join(dirname(fileURLToPath(import.meta.url)), '..');
15
- const logPath = getDocInitLogPath();
16
- mkdirSync(dirname(logPath), { recursive: true });
17
-
18
- const nativeResult = await ensureBetterSqlite3ForDocs();
19
- if (!nativeResult.ok && !nativeResult.skipped) {
20
- console.warn(
21
- `[deveco-cli] better-sqlite3 install via npm failed; docs search will use sqlite-wasm fallback.\n` +
22
- `${nativeResult.error ?? ''}\n`
23
- );
24
- }
25
-
26
- const jiebaResult = await ensureJiebaWasmForDocs();
27
- if (!jiebaResult.ok && !jiebaResult.skipped) {
28
- console.warn(
29
- `[deveco-cli] jieba wasm install via npm failed; docs search may fail on this machine.\n` +
30
- `${jiebaResult.error ?? ''}\n`
31
- );
32
- }
33
12
  const initScript = join(root, 'dist', 'internal', 'doc-init-background.js');
34
13
 
35
14
  if (!existsSync(initScript)) {
@@ -1,51 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Huawei Device Co., Ltd.
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { appendFile, mkdir } from 'fs/promises';
7
- import { dirname } from 'path';
8
- import { getDocInitLogPath } from './lib/doc-init-log-path.mjs';
9
- import {
10
- installBetterSqlite3ViaNpm,
11
- isBetterSqlite3Loadable,
12
- resolveTargetVersion,
13
- } from './lib/better-sqlite3-vendor.mjs';
14
-
15
- async function appendInstallLog(message) {
16
- try {
17
- const logPath = getDocInitLogPath();
18
- await mkdir(dirname(logPath), { recursive: true });
19
- await appendFile(
20
- logPath,
21
- `${new Date().toISOString()} [better-sqlite3] ${message}\n`
22
- );
23
- } catch {
24
- // ignore logging failures
25
- }
26
- }
27
-
28
- /** @deprecated Use installBetterSqlite3ViaNpm */
29
- export const ensureBetterSqlite3NativeBinary = installBetterSqlite3ViaNpm;
30
-
31
- export async function ensureBetterSqlite3ForDocs() {
32
- const targetVersion = resolveTargetVersion();
33
- await appendInstallLog(
34
- `ensure better-sqlite3@${targetVersion} for Node ${process.version} via npm install`
35
- );
36
-
37
- if (await isBetterSqlite3Loadable()) {
38
- await appendInstallLog('skip: better-sqlite3 already loadable');
39
- return { ok: true, skipped: true, reason: 'already-installed' };
40
- }
41
-
42
- const result = await installBetterSqlite3ViaNpm();
43
- if (result.ok) {
44
- await appendInstallLog(`installed better-sqlite3@${targetVersion} via npm`);
45
- } else {
46
- await appendInstallLog(
47
- `npm install failed (${result.reason}): ${result.error ?? 'unknown error'}`
48
- );
49
- }
50
- return result;
51
- }
@@ -1,47 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Huawei Device Co., Ltd.
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { appendFile, mkdir } from 'fs/promises';
7
- import { dirname } from 'path';
8
- import { getDocInitLogPath } from './lib/doc-init-log-path.mjs';
9
- import { installJiebaWasmViaNpm } from './lib/jieba-wasm-vendor.mjs';
10
-
11
- async function appendInstallLog(message) {
12
- try {
13
- const logPath = getDocInitLogPath();
14
- await mkdir(dirname(logPath), { recursive: true });
15
- await appendFile(
16
- logPath,
17
- `${new Date().toISOString()} [jieba-wasm] ${message}\n`
18
- );
19
- } catch {
20
- // ignore logging failures
21
- }
22
- }
23
-
24
- export async function ensureJiebaWasmForDocs() {
25
- await appendInstallLog(
26
- `ensure @node-rs/jieba-wasm32-wasi@2.0.1 for Node ${process.version}`
27
- );
28
- const result = await installJiebaWasmViaNpm();
29
- if (result.skipped) {
30
- if (result.reason === 'already-installed') {
31
- await appendInstallLog('skip: jieba wasm32-wasi already loadable');
32
- } else if (result.reason === 'native-available') {
33
- await appendInstallLog('skip: jieba native already loadable');
34
- } else {
35
- await appendInstallLog(`skip: ${result.reason}`);
36
- }
37
- } else if (result.ok) {
38
- await appendInstallLog(
39
- 'installed @node-rs/jieba-wasm32-wasi@2.0.1 via npm'
40
- );
41
- } else {
42
- await appendInstallLog(
43
- `npm install failed (${result.reason}): ${result.error ?? 'unknown error'}`
44
- );
45
- }
46
- return result;
47
- }
@@ -1,129 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Huawei Device Co., Ltd.
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { dirname, join } from 'path';
7
- import { fileURLToPath } from 'url';
8
- import { existsSync } from 'fs';
9
- import { readFile, stat, writeFile } from 'fs/promises';
10
- import { spawnSync } from 'child_process';
11
-
12
- export const BETTER_SQLITE3_VERSION_LEGACY = '11.10.0';
13
- export const BETTER_SQLITE3_VERSION_NODE20 = '12.9.0';
14
- export const BETTER_SQLITE3_VERSION_NODE21 = '9.6.0';
15
- export const BETTER_SQLITE3_VERSION_LATEST = '12.11.1';
16
-
17
- const scriptDir = dirname(fileURLToPath(import.meta.url));
18
- export const packageRoot = join(scriptDir, '..', '..');
19
-
20
- export function resolveTargetVersion(nodeVersion = process.version) {
21
- const major = Number(nodeVersion.slice(1).split('.')[0]);
22
- if (major === 18) {
23
- return BETTER_SQLITE3_VERSION_LEGACY;
24
- }
25
- if (major === 20 || major === 23) {
26
- return BETTER_SQLITE3_VERSION_NODE20;
27
- }
28
- if (major === 21) {
29
- return BETTER_SQLITE3_VERSION_NODE21;
30
- }
31
- return BETTER_SQLITE3_VERSION_LATEST;
32
- }
33
-
34
- export function isUnsupportedNodeVersion(nodeVersion = process.version) {
35
- return Number(nodeVersion.slice(1).split('.')[0]) === 19;
36
- }
37
-
38
- function resolveNpmCliPath() {
39
- const nodeDir = dirname(process.execPath);
40
- const candidates = [
41
- join(nodeDir, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
42
- join(nodeDir, '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
43
- ];
44
- return candidates.find((candidate) => existsSync(candidate)) ?? null;
45
- }
46
-
47
- function quoteWindowsCmdArg(arg) {
48
- return /\s/.test(arg) ? `"${arg.replace(/"/g, '\\"')}"` : arg;
49
- }
50
-
51
- function spawnDetail(result) {
52
- return [result.stderr, result.stdout, result.error?.message]
53
- .filter(Boolean)
54
- .join('\n')
55
- .trim();
56
- }
57
-
58
- export function runNpmInstallBetterSqlite3(targetVersion) {
59
- const args = ['install', `better-sqlite3@${targetVersion}`, '--no-save'];
60
- const npmCli = resolveNpmCliPath();
61
- if (npmCli) {
62
- return spawnSync(process.execPath, [npmCli, ...args], {
63
- cwd: packageRoot,
64
- stdio: 'pipe',
65
- encoding: 'utf-8',
66
- });
67
- }
68
-
69
- if (process.platform === 'win32') {
70
- const command = ['npm', ...args].map(quoteWindowsCmdArg).join(' ');
71
- return spawnSync(command, {
72
- cwd: packageRoot,
73
- stdio: 'pipe',
74
- encoding: 'utf-8',
75
- shell: true,
76
- });
77
- }
78
-
79
- return spawnSync('npm', args, {
80
- cwd: packageRoot,
81
- stdio: 'pipe',
82
- encoding: 'utf-8',
83
- });
84
- }
85
-
86
- export async function isBetterSqlite3Loadable() {
87
- try {
88
- await import('better-sqlite3');
89
- return true;
90
- } catch {
91
- return false;
92
- }
93
- }
94
-
95
- export async function installBetterSqlite3ViaNpm(nodeVersion = process.version) {
96
- if (isUnsupportedNodeVersion(nodeVersion)) {
97
- return {
98
- ok: false,
99
- reason: 'unsupported-node',
100
- error: 'Node.js 19 is not supported for better-sqlite3',
101
- };
102
- }
103
-
104
- if (await isBetterSqlite3Loadable()) {
105
- return { ok: true, skipped: true, reason: 'already-installed' };
106
- }
107
-
108
- const targetVersion = resolveTargetVersion(nodeVersion);
109
- const result = runNpmInstallBetterSqlite3(targetVersion);
110
- if (result.status !== 0) {
111
- return {
112
- ok: false,
113
- reason: 'npm-install-failed',
114
- version: targetVersion,
115
- error: spawnDetail(result) || `exit ${result.status ?? 'null'}`,
116
- };
117
- }
118
-
119
- if (!(await isBetterSqlite3Loadable())) {
120
- return {
121
- ok: false,
122
- reason: 'load-failed',
123
- version: targetVersion,
124
- error: 'npm install finished but better-sqlite3 still cannot be imported',
125
- };
126
- }
127
-
128
- return { ok: true, version: targetVersion, method: 'npm' };
129
- }