@deveco-test/deveco-cli 1.3.0-Test.8 → 1.3.1-Test.1

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 h from"fs";import*as T from"path";import Pi from"adm-zip";import Oi from"proper-lockfile";import Li from"ora";import*as w from"fs";import*as at from"path";var Bt=["harmonyos-guides","harmonyos-references","best-practices","harmonyos-faqs","harmonyos-releases","harmonyos-roadmap"],dt={"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 H="1.9.1",Qi=48*1024*1024,Ae=280,we=6,De=100,Ie=3,Te=28,Mt=10,Ce=/API参考|APIReference/i;var Re=6,mt=700,kt=250,vt=400,Ne=1320,Pe=120,Oe=450,Le=250,Be=500,Me=480,ke=80,ve=200,Fe=60,ze=200,He=40,je=200,Ue=200,Ze=40,j=500,$e=Object.fromEntries(Bt.map((t,e)=>[dt[t],e])),O=Object.fromEntries(Bt.map((t,e)=>[t,e]));import*as K from"fs";import*as m from"path";import{fileURLToPath as Ye}from"url";import*as L from"fs";import*as Qe from"path";import{homedir as Sr}from"os";import*as Ge from"fs";import*as E from"path";function Y(t,e){let n=E.relative(e,t);return n===""||!E.isAbsolute(n)&&!n.startsWith(`..${E.sep}`)&&n!==".."}function U(t){let e=E.resolve(t),n=[],r=e;for(;;)try{let o=Ge.realpathSync(r);return n.length===0?o:E.join(o,...n.reverse())}catch(o){if(o.code!=="ENOENT")throw o;let i=E.dirname(r);if(i===r)return e;n.push(E.basename(r)),r=i}}function Xe(t,e){let n=U(e),r=U(t);return Y(r,n)?r:null}function Ft(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=Ft(t);if(!e)throw new Error("Path must not be empty.");return U(e)}var yr="deveco-cli",zt,k=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===""?"":Ft(t))||Qe.join(Sr(),".local","share",yr);try{return We(n)}catch(r){throw new k(r instanceof Error?r.message:String(r))}}async function Je(){let t=qe();await L.promises.mkdir(t,{recursive:!0});let e;try{e=await L.promises.realpath(t)}catch(r){throw new k(`DEVECO_CLI_DATA_DIR is not usable: ${r instanceof Error?r.message:String(r)}`)}if(!(await L.promises.stat(e)).isDirectory())throw new k("DEVECO_CLI_DATA_DIR must be a writable directory.");return zt=e,e}function V(){if(zt!==void 0)return zt;let t=qe();try{if(L.existsSync(t))return L.realpathSync(t)}catch{}return t}var xr="docs";function Z(){return m.join(V(),xr)}function g(){return m.join(Z(),".index")}function ft(){return m.join(g(),"build.lock")}function tt(){return m.join(g(),"build-status.json")}function $(){return m.join(g(),"build-meta.json")}function G(){return m.join(g(),"search.db")}function et(){return m.join(g(),"sqlite-backend.json")}function nt(){return m.join(g(),"jieba-backend.json")}function C(){return m.join(g(),".tmp")}function Er(){return m.join(V(),"logs")}function Ht(){return m.join(Er(),"doc-init.log")}function _r(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(_r(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 br(...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=K.realpathSync(e);for(let r of br(...t))try{let o=K.lstatSync(r);if(o.isSymbolicLink()||!o.isFile())throw new Error(`Unsafe documentation package asset: ${t.join("/")} must be a regular file.`);let i=K.realpathSync(r);if(!Y(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 v(){return tn("docs.zip")}function jt(){return tn("index.zip")}function en(){return m.join(Ke(),"index","data")}import*as R from"fs";import*as F from"path";var N=["harmonyos-terms.txt","harmonyos-synonyms.json","harmonyos-stopwords.txt"],Ut=class extends Error{constructor(e){super(e),this.name="LexiconNotFoundError"}};var Zt=null;function $t(t){Zt=t}function nn(){if(Zt)return Zt;let t=g();if(N.every(o=>R.existsSync(F.join(t,o))))return t;let n=en();if(N.every(o=>R.existsSync(F.join(n,o))))return n;throw new Ut("Lexicon files not found. Install the documentation index first (index.zip).")}function rt(t){let e=F.join(nn(),t);return R.readFileSync(e,"utf-8")}function rn(t,e){return R.readFileSync(F.join(e,t),"utf-8")}async function on(t,e=nn()){await R.promises.mkdir(t,{recursive:!0});for(let n of N){let r=F.join(e,n),o=F.join(t,n);await R.promises.copyFile(r,o)}}import*as Gt from"fs";import*as Ar from"yauzl";function Xt(){let t=v();return t!==null&&Gt.existsSync(t)}import*as y from"fs";import*as P from"path";import sn from"adm-zip";import*as ot from"fs";import*as gt from"path";var pt=class extends Error{constructor(e){super(`Unsafe documentation path: ${e}`),this.name="DocPathSafetyError"}};function qt(t){return t instanceof k||t instanceof pt||t instanceof Error&&(t.name==="CliDataDirError"||t.name==="DocPathSafetyError")}function Jt(t){return new pt(t)}function wr(){return U(V())}function Qt(t,e,n){let r=Xe(t,e);if(r===null)throw Jt(`${n} resolves outside the data directory.`);return r}async function Wt(t,e){await ot.promises.mkdir(t,{recursive:!0});let n=Qt(t,e,"directory");if(!(await ot.promises.stat(n)).isDirectory())throw Jt("path must be a directory.")}function it(t){let e=wr();try{let n=Qt(t,e,"file");if(!ot.statSync(n).isFile())throw Jt("path must be a regular file.")}catch(n){if(n.code==="ENOENT"){Qt(gt.dirname(t),e,"file parent");return}throw n}}async function st(t={}){let e=t.mode??"write",n=await Je();await Wt(Z(),n),await Wt(g(),n),e==="write"&&await Wt(C(),n);for(let r of[G(),$(),tt(),ft(),nt(),et(),...N.map(o=>gt.join(g(),o))])it(r)}var Yt=["search.db","build-meta.json",...N],Dr=["corpus.json","corpus-offsets.json","orama.dpack"];async function Ir(t){for(let e of Dr)await y.promises.rm(P.join(t,e),{force:!0})}async function Tr(t){let e=await y.promises.readdir(t,{withFileTypes:!0});for(let n of e)n.name!==".index"&&await y.promises.rm(P.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 Cr(t){let e=g();await y.promises.mkdir(e,{recursive:!0});for(let n of Yt){let r=P.join(e,n);await y.promises.rm(r,{force:!0}),await y.promises.rename(P.join(t,n),r)}await Ir(e),await y.promises.rm(C(),{recursive:!0,force:!0})}function cn(t){let e=jt();if(!e)return!1;try{let n=an(e);return n.indexVersion===H&&n.docsZipSha256===t&&n.segmentCount>0}catch{return!1}}async function un(t){await st({mode:"write"});let e=jt();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=C();await y.promises.rm(r,{recursive:!0,force:!0}),await y.promises.mkdir(r,{recursive:!0});let o=new sn(e);for(let s of Yt){let a=o.getEntry(s);if(!a)throw new Error(`index.zip is missing ${s}`);await y.promises.writeFile(P.join(r,s),a.getData())}let i=JSON.parse(await y.promises.readFile(P.join(r,"build-meta.json"),"utf-8"));if(!y.existsSync(P.join(r,"search.db")))throw new Error("index.zip is missing search.db");return await Cr(r),await y.promises.mkdir(Z(),{recursive:!0}),await Tr(Z()),i}async function ln(){await y.promises.rm(C(),{recursive:!0,force:!0});let t=g();for(let e of Yt)await y.promises.rm(P.join(t,e),{force:!0})}import{createHash as dn}from"crypto";import*as mn from"fs";async function ht(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):rt(t);return fn(n)}function St(t){return pn("harmonyos-synonyms.json",t)}function yt(t){return pn("harmonyos-terms.txt",t)}var Rr={state:"idle",phase:0,phaseLabel:"Idle",current:0,total:0,message:"",startedAt:0,updatedAt:0,error:null};async function gn(){try{let t=await w.promises.readFile(tt(),"utf-8");return JSON.parse(t)}catch{return{...Rr}}}async function Vt(t){let e=tt();await w.promises.mkdir(at.dirname(e),{recursive:!0}),await w.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 B(t){let n={...await gn(),...t,updatedAt:Date.now()};return await Vt(n),n}async function Kt(){let t=v();return t?ht(t):null}async function te(){try{let t=await w.promises.readFile($(),"utf-8");return JSON.parse(t)}catch{return null}}async function ee(t=!1){if(t)return"no-index";let e=await te();if(!e||e.segmentCount===0)return"no-index";let n=await Kt();return n&&e.docsZipSha256!==n?"docs-changed":e.indexVersion!==H?"engine-upgraded":e.termsHash!==yt()?"terms-changed":e.synonymsHash!==St()?"synonyms-changed":null}function ne(){if(!Xt()||!w.existsSync(G())||!w.existsSync($()))return!1;let t=at.dirname(G());if(!N.every(e=>w.existsSync(at.join(t,e))))return!1;try{let e=w.readFileSync($(),"utf-8");return JSON.parse(e).segmentCount>0}catch{return!1}}async function Sn(t=!1){return t?!0:Xt()?ne()?await ee()!==null:!0:!1}import*as x from"fs";import*as lr from"os";import*as _ from"path";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 Nr=/@ohos\.[a-z][a-zA-Z0-9.]+/gi,Pr=/\b[a-z][a-z0-9]*[A-Z][a-zA-Z0-9]+\b/g,Or=/[A-Z][a-zA-Z0-9]{2,}/g,Lr=/@[A-Z][a-zA-Z0-9]*/g,Br=/[a-z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]+/g,_n=6,Mr=/^[a-z][a-z0-9]{2,}$/,kr=/^([a-z][a-z0-9]{2,})\s+([a-z][a-z0-9]{2,})$/,vr=/^@ohos\.[a-z][a-zA-Z0-9.]+$/i,Fr=/^[a-z][a-z0-9]*[A-Z][a-zA-Z0-9]+$/,zr=/^[A-Z][a-zA-Z0-9]+$/;function re(t){return vr.test(t)}function Hr(t){return Fr.test(t)&&t.length>=_n}function jr(t){return zr.test(t)}function oe(t){return re(t)||Hr(t)||jr(t)}function Ur(t){let e=t.trim().toLowerCase();return En.has(e)?!1:yn.has(e)}function Zr(t,e){let n=e.trim().charAt(0).toUpperCase(),r=e.trim().slice(1).toLowerCase();return`${t.trim().toLowerCase()}${n}${r}`}function xt(t){let n=t.replace(/^@ohos\./i,"").split(".").filter(Boolean);return n[n.length-1]?.trim()||void 0}function ie(t){return[...t.matchAll(Nr)].map(e=>e[0])}function se(t,e=_n){let n=[];for(let r of t.matchAll(Pr))r[0].length>=e&&n.push(r[0]);return n}function X(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 D(t,e){let n=e.trim();if(!n)return;t.add(n);let r=n.toLowerCase();r!==n&&t.add(r)}function $r(t){let e=new Set;D(e,t);let n=xt(t);return n&&D(e,n),X([...e])}function ae(t){if(re(t))return $r(t);let e=new Set;return D(e,t),X([...e])}function ce(t){let e=t.trim();if(/[A-Z]/.test(e))return null;let n=e.match(kr);if(!n)return null;let r=n[1].toLowerCase(),o=n[2].toLowerCase();if(!Mr.test(r)||xn.has(r)||!Ur(o))return null;let i=Zr(r,o);return{first:r,second:o,camelCase:i,lower:i.toLowerCase()}}function bn(t){let e=ce(t.trim());return!e||e.second!=="manager"?null:e}function ue(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(oe(e))return ae(e);let n=new Set;for(let r of ie(t)){D(n,r);let o=xt(r);o&&D(n,o)}for(let r of se(t))D(n,r);for(let r of t.matchAll(Lr))n.add(r[0]);for(let r of t.matchAll(Br))n.add(r[0]);for(let r of t.matchAll(Or))r[0].length>=4&&n.add(r[0]);return X([...n])}function wn(t){let e=t.trim();if(oe(e))return ae(e);let n=new Set,r=ce(e);r&&D(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 X([...n])}var I={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 In(t){return I.pureApiSymbol.test(t.trim())}function Dn(t){let e=t.trim();return I.stageModelExact.test(e)||I.stageModelEnglishExact.test(e)}var Gr=[{matches:t=>I.uiAbilityLifecycleBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.85},{catalog:"harmonyos-references",multiplier:.65},{catalog:"harmonyos-faqs",multiplier:.82}]},{matches:t=>Dn(t),weights:[{catalog:"harmonyos-guides",multiplier:1.85},{catalog:"harmonyos-references",multiplier:.55},{catalog:"harmonyos-faqs",multiplier:.85}]},{matches:t=>!Dn(t)&&I.stageModel.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"harmonyos-references",multiplier:.65}]},{matches:t=>I.entryAbilityPage.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.75},{catalog:"harmonyos-references",multiplier:.48}]},{matches:t=>I.declarePermissionBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"best-practices",multiplier:.68}]},{matches:t=>I.stateDecoratorBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.75},{catalog:"harmonyos-references",multiplier:.42}]},{matches:t=>I.stateManagement.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.6},{catalog:"best-practices",multiplier:.78}]},{matches:t=>I.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=>I.dialogPopupBoost.test(t),weights:[{catalog:"harmonyos-guides",multiplier:1.65},{catalog:"harmonyos-faqs",multiplier:.72},{catalog:"best-practices",multiplier:.72}]}];function Xr(t,e){for(let{catalog:n,multiplier:r}of e){let o=O[n];t.set(o,(t.get(o)??1)*r)}}function Tn(t,e){for(let n of Gr)n.matches(t)&&Xr(e,n.weights)}import*as W from"fs";import*as Rn from"path";function z(t){process.env.DEVECO_CLI_DEBUG&&console.log(`[DEBUG] ${t}`)}var Et=null,le=null,de=null;function Wr(){return W.existsSync(nt())}function Qr(t){let e=nt(),n={backend:"jieba-wasm",reason:"native-jieba-load-failed",message:t,createdAt:new Date().toISOString()};W.mkdirSync(Rn.dirname(e),{recursive:!0}),it(e),W.writeFileSync(e,JSON.stringify(n,null,2))}function qr(){if(Et)return Et;let t=rt("harmonyos-stopwords.txt");return Et=new Set(t.split(`
2
- `).map(e=>e.trim()).filter(Boolean)),Et}function Jr(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 Yr(t){let e=qr(),n=[];for(let r of Jr(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=rt("harmonyos-terms.txt");return n.loadDict(Buffer.from(r,"utf-8")),n}async function Vr(){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 Kr(){if(Wr())return await Cn();try{let e=await Vr();return z("doc-index: using @node-rs/jieba backend"),e}catch(e){let n=e instanceof Error?e.message:String(e);Qr(n),z(`doc-index: @node-rs/jieba unavailable (${n}); falling back to wasm32-wasi`)}let t=await Cn();return z("doc-index: using @node-rs/jieba-wasm32-wasi backend"),t}async function Q(){return le||(de||(de=Kr().then(t=>(le=t,t))),de)}async function to(t){let e=await Q();return Yr(e.cutForSearch(t,!0))}async function _t(t,e){let n=t.trim();if(!n||e<=0)return"";let r=(await to(n)).join(" ");return r.length<=e?r:r.slice(0,e)}async function eo(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 bt(t){let e=!!t.sectionTitle.trim(),n=t.titleTokens.trim(),r=e?Me:Ne,o=e?ve:Oe,i=e?await eo(t.apiSymbols,o):await _t(t.apiSymbols.join(" "),o),a=(await Promise.all([_t(n,e?ke:Pe),Promise.resolve(i),_t(t.headingsText,e?Fe:Le),_t(t.bodySample,e?ze:Be)])).filter(Boolean).join(" ");return a.length<=r?a:a.slice(0,r)}var Pn=["harmonyos-releases","harmonyos-roadmap"],no=new Set(Pn.map(t=>O[t])),Ba=Pn.map(t=>`${dt[t]}/`);function ro(t){return no.has(t)}function On(t){let e=[],n=[];for(let r of t)ro(r.catalog_id)?n.push(r):e.push(r);return[...e,...n]}var oo=[{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 ct(t,e,n){let r=O[e];t.set(r,(t.get(r)??1)*n)}function io(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)){ct(e,"harmonyos-guides",1.45),ct(e,"harmonyos-references",1.35);return}(o||i)&&ct(e,"harmonyos-references",1.55),/\b[A-Z][a-zA-Z]*(Gesture|Dialog|Sheet|Transition|Recognizer)\b/.test(n)&&ct(e,"harmonyos-references",1.75)}function Ln(t){let e=new Map,n=t.trim();if(!n)return e;let r=In(n);io(n,e),Tn(n,e);for(let o of oo)o.pattern.test(n)&&(o.skipForPureApiSymbol&&r||ct(e,o.catalog,o.multiplier));return e}import*as J from"fs";import*as jn from"path";var so=[" ","\u3002","\uFF0C","\uFF1B","\u3001",".","!","?"];function Bn(t,e){let n=-1;for(let r of so){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=Ue,contextChars:o=Ze,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(Lt=>Lt.trim()).filter(Boolean),c=0;for(let Lt of a){let be=s.toLowerCase().indexOf(Lt.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),b=Bn(u,r-25);b>=0&&(p=f+b);let S=s.slice(f,p).trim(),A=f>0?"...":"",hr=p<s.length||i?"...":"";return`${A}${S}${hr}`}var ao=`
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
- `,co=`
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
- `,uo=3.5,lo=1.4,mo=4,fo=1.8,po=1.35,go=3.5,ho=1.8,So=120,vn=6;function fe(t){return t.toLowerCase().replace(/[^\p{L}\p{N}@.]+/gu,"")}function yo(t){return t.split(/[^\p{L}\p{N}@.]+/u).map(fe).filter(e=>e.length>=2)}function xo(t,e){return e.length>1&&e.every(n=>t.includes(n))}function Eo(t){return/^[a-z0-9]{1,4}$/.test(t.trim().toLowerCase())}function _o(t,e){return t===e?go:t.startsWith(e)||t.includes(`@ohos.${e}`)?ho:1}function bo(t,e){let n=fe(e);if(n.length<2)return 1;let r=fe(t.doc_title);if(Eo(e))return _o(r,n);if(r.includes(n))return mo;if(n.length>=vn&&r.includes(n.slice(0,vn)))return fo;let o=yo(e);return xo(r,o)?po:1}function Ao(t,e){return e<=1?t:t<0?t*e:t/e}function At(t,e,n,r){let o=t.bm25/(e.get(t.catalog_id)??1);return o=Ao(o,bo(t,n)),r&&ue(t.doc_title,t.section_title,r)&&(o/=uo,t.catalog_id===O["harmonyos-references"]&&(o/=lo)),o}function me(t,e,n,r){return t.reduce((o,i)=>At(i,e,n,r)<At(o,e,n,r)?i:o)}function wo(t,e){return e.some(n=>t.section_title.includes(n)||t.doc_title.includes(n))}function Do(t,e,n,r,o){if(o){let i=t.filter(s=>ue(s.doc_title,s.section_title,o));if(i.length>0)return me(i,n,r,o)}if(e.length>0){let i=t.filter(s=>wo(s,e));if(i.length>0)return me(i,n,r,o)}return me(t,n,r,o)}function Fn(t,e,n,r,o){let i=Ln(e),s=wn(e),c=bn(e)?.camelCase,f=new Map;for(let S of t){let A=f.get(S.document_id)??[];A.push(S),f.set(S.document_id,A)}let p=[];for(let S of f.values())p.push(Do(S,s,i,n,c));let u=p.sort((S,A)=>At(S,i,n,c)-At(A,i,n,c));return(o?On(u):u).slice(0,r)}function wt(t,e,n,r,o,i){let s=e?O[e]:void 0,a=Math.max(n,n*Re,So),c=s===void 0?t.all(ao,r,a):t.all(co,r,s,a);return(s===void 0?Fn(c,i,o,n,!0):Fn(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 Dt=`
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 q=null,pe=null;function Io(){q?.close(),q=null,pe=null}function To(t,e){if(q&&pe===e)return q;q?.close();let n=new t(e,{readonly:!0,fileMustExist:!0});return q=n,pe=e,n.pragma("mmap_size = 268435456"),n.pragma("cache_size = -8000"),n.pragma("query_only = ON"),n}function Co(t,e){let n=new t(e);return n.pragma("journal_mode = OFF"),n.pragma("synchronous = OFF"),n.pragma("temp_store = MEMORY"),n.exec(Dt),n}function Ro(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 No(t,e,n,r){await Q();let o=Co(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+=j){let f=n.slice(c,c+j),p=await Promise.all(f.map(async b=>({source:b,searchText:await bt(b)})));o.transaction(b=>{for(let S of b){let A=Ro(o,i,S.source);s.run(A,S.source.sectionTitle,S.source.leadText,S.searchText,S.source.excerptTruncated?1:0)}})(p),await r?.(Math.min(c+f.length,a),a)}o.exec("ANALYZE"),o.exec("VACUUM"),o.close()}function Po(t,e,n,r,o,i,s){let a=To(t,e);return wt({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:Io,buildSearchIndex:(n,r,o)=>No(e,n,r,o),searchIndex:(n,r,o,i,s,a,c)=>Promise.resolve(Po(e,i,r,o,s,a,c))}}import{readFile as Oo,stat as Lo,writeFile as Bo}from"fs/promises";var ge=null,M=null;async function he(){return ge||(ge=(async()=>{let t=(await import("@sqlite.org/sqlite-wasm")).default;return t()})()),ge}function Mo(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 ko(t){let e=await Lo(t);if(M&&M.dbPath===t&&M.mtimeMs===e.mtimeMs)return M.db;M?.db.close();let n=await he(),r=n.capi,o=n.wasm,i=new Uint8Array(await Oo(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),M={dbPath:t,mtimeMs:e.mtimeMs,db:a},a}function Hn(){M?.db.close(),M=null}async function vo(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 Fo(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 zo(t,e,n){await Q();let r=await he(),o=new r.oo1.DB(":memory:","c");o.exec(Dt);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=Fo(o,i,s),f=e.length;for(let u=0;u<f;u+=j){let b=e.slice(u,u+j),S=await Promise.all(b.map(async A=>({source:A,searchText:await bt(A)})));await vo(o,a,c,S),await n?.(Math.min(u+b.length,f),f)}o.exec("ANALYZE");let p=r.capi.sqlite3_js_db_export(o);await Bo(t,p),o.close(),Hn()}async function Ho(t,e,n,r,o,i){let s=await ko(t);return wt(Mo(s),e,n,r,o,i)}async function Se(){return await he(),{kind:"sqlite-wasm",resetCache:Hn,buildSearchIndex:zo,searchIndex:(t,e,n,r,o,i,s)=>Ho(r,e,n,o,i,s)}}var It=null,ye=null;function jo(){return J.existsSync(et())}function Uo(t){let e=et(),n={backend:"sqlite-wasm",reason:"better-sqlite3-load-failed",message:t,createdAt:new Date().toISOString()};J.mkdirSync(jn.dirname(e),{recursive:!0}),it(e),J.writeFileSync(e,JSON.stringify(n,null,2))}async function Zo(){if(jo())return Se();try{let t=await zn();return z("doc-index: using better-sqlite3 SQLite backend"),t}catch(t){let e=t instanceof Error?t.message:String(t);Uo(e),z(`doc-index: better-sqlite3 unavailable (${e}); falling back to sqlite-wasm`)}return Se()}async function xe(){return It||(It=Zo().then(t=>(ye=t,t))),It}function Un(){ye?.resetCache(),It=null,ye=null}function Tt(){Un()}async function Zn(t,e,n){await(await xe()).buildSearchIndex(t,e,n)}import{unified as Yn}from"unified";import Vn from"remark-parse";import Kn from"remark-gfm";import{toString as Rt}from"mdast-util-to-string";var $o=/^(.+?)(\d+\+)?(对象|枚举|错误码)说明$/,Go=/^\[h2\]([A-Za-z][A-Za-z0-9]*)(\d+\+)?$/,Xo=/^(.{2,20}?)\s*[((]([A-Za-z][a-zA-Z0-9]{1,40})[))]\s*$/,Wo=/^([A-Za-z@][A-Za-z0-9@]*?)(\d+\+)?$/,Qo=/^(系统能力|元服务API|参数|返回值|说明|\*\*|表格|\|)/;function Ct(t){let e=t.trim(),n=e.match(Wo);return n?n[1]:e}function qo(t){let e=t.match($o);if(!e)return;let n=Ct(e[1].trim());return{displayTitle:t,symbolName:n,searchExtras:[n,e[3]]}}function Jo(t){let e=Ct(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 ut(t){let e=t.trim();return e?qo(e)??(()=>{let n=e.match(Go);if(n){let r=n[1];return{displayTitle:e,symbolName:r,searchExtras:[r]}}})()??(()=>{let n=e.match(Xo);if(!n)return;let r=n[1].trim(),o=n[2].trim();return{displayTitle:e,symbolName:o,searchExtras:[r,o]}})()??Jo(e)??{displayTitle:e,searchExtras:[]}:{displayTitle:"",searchExtras:[]}}function Yo(t){if(t.length<2||t.length>36||Qo.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(Yo(n))return n}return""}function Gn(t,e,n){let r=[t,...n.searchExtras,e].filter(Boolean);return[...new Set(r)].join(" ")}var Vo=/[A-Z][a-zA-Z0-9]+(?:\.[a-zA-Z][a-zA-Z0-9]+)*/g,lt=/@[A-Z][a-zA-Z]+/g,Ko=/^[A-Z][A-Za-z0-9]*\.[A-Za-z][A-Za-z0-9]+/,ti=/^[A-Z][A-Za-z0-9]+(?:\([^)]*\))?$/,ei=/^[a-z0-9]+(?:[-_][a-z0-9]+)+$/,ni=new Set(["API","Action","Code","Connect","Connection","Context","Direction","Element","Elements","Entry","Focused","Module","Modules","Name","Names","Stage","Type","Types","Value","Values","Rect","Error"]),ri=new Set(["HAP","HSP","HAR","NAPI","CAPI","NDK","ArkTS","ArkUI","OHPM"]),oi=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 ie(o)){D(n,i);let s=xt(i);s&&D(n,s)}for(let i of se(o))D(n,i);for(let i of o.matchAll(Vo)){let s=i[0];ii(s)&&n.add(s)}for(let i of o.matchAll(lt))n.add(i[0])}return X([...n])}function ii(t){let e=t.trim();if(!e||lt.test(e))return!!e;if(e.includes(".")){let n=e.split(".")[0]??"";return oi.has(n)?!1:/^[A-Z]/.test(n)}return ni.has(e)?!1:ri.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||ei.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=ui(t,"").trim(),o=e.fileName.trim();return n&&!Xn(n)?n:r&&!Xn(r)?r:n||r||o}function nr(t){return Ko.test(t.trim())}function Ee(t){let e=t.trim().replace(/\([^)]*\)$/,""),n=Ct(e);return ti.test(n)}function Nt(t){let e=t.trim();return e?lt.test(e)||nr(e)||Ee(e)?!0:!!ut(e).symbolName:!1}function si(t){let e=t.trim();return!(!e||nr(e)||Ee(e))}function ai(t){let e=new Set,n=[];for(let r of t){let o=r.trim();!si(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 ci(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(ci),[...n,...o].slice(0,He)}function Pt(t){return t.replace(/\s+/g," ").trim()}function Qn(t){return t.replace(/\\([\\`*_{}[\]()#+.!-])/g,"$1")}function ui(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=Pt(t.join(" "));if(e.length<=mt)return e;let n=e.slice(0,mt);return e.length<=mt+kt?n:`${n} ${e.slice(-kt)}`}function li(t){let e=ai(t).join(" ");return e.length<=vt?e:e.slice(0,vt)}function ir(t){let e=Pt(t),{text:n,excerptTruncated:r}=Mn(e,je);return{leadText:n,excerptTruncated:r}}function di(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=Pt(Rt(t));n&&e.bodyParts.push(n)}function mi(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=Rt(a).trim();if(a.depth>=4&&c&&Nt(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 fi(t){return Ce.test(t)}function pi(t){return t.filter(e=>e.sectionTitle&&Nt(e.sectionTitle)).length}function gi(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||lt.test(e)?lt.test(e):/对象说明$|枚举说明$/.test(e)?!0:Ee(e)}function hi(t){let e=t.filter(u=>!u.sectionTitle||!Nt(u.sectionTitle)),n=t.filter(u=>u.sectionTitle&&Nt(u.sectionTitle)),r=n.filter(u=>qn(u.sectionTitle)),o=n.filter(u=>!qn(u.sectionTitle)),i=Math.max(0,Te-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+=Mt)p.push(gi(f.slice(u,u+Mt)));return[...e,...r,...s,...c,...p]}function Si(t,e,n){let r=t.split(/\r?\n/).length,o=pi(e);return o===0?!1:fi(n)?r>=De&&o>=Ie:r>=Ae&&o>=we}var yi=/^\[h2\][A-Za-z]/;function Jn(t){return yi.test(t.trim())}function ar(t){if(!t.includes(" | ")){let n=ut(t);return n.symbolName?[n.symbolName]:[]}let e=[];for(let n of t.split(" | ")){let r=ut(n.trim()).symbolName;r&&e.push(r)}return e}function xi(t,e,n,r){let o=ar(t),i=tr(n,r);return e.symbolName&&i.push(e.symbolName),rr([...o,...i],o)}function Ei(t,e){let n=or(t.bodyParts),r=t.sectionTitle.trim(),o=ut(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}=di(n,r);return{documentId:e.documentId,catalogId:e.catalogId,docTitle:e.docTitle,sectionTitle:r,titleTokens:c,headingsText:s,apiSymbols:xi(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=Rt(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=Pt(Rt(n));r&&e.bodyParts.push(r)}}function _i(t){let e=Yn().use(Vn).use(Kn).parse(t),n={headings:[],bodyParts:[],codeBlocks:[]};return cr(e.children,n),n}function bi(t,e){let n=_i(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:li(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=mi(t);return Si(t,r,e.documentId)?hi(r).filter(o=>o.sectionTitle||o.bodyParts.length>0||o.codeBlocks.length>0).map(o=>Ei(o,{...e,docTitle:n})):[bi(t,{...e,docTitle:n})]}async function Ai(t){let e=[];async function n(r){let o=await x.promises.readdir(r,{withFileTypes:!0});for(let i of o){if(i.name.startsWith("."))continue;let s=_.join(r,i.name);i.isDirectory()?await n(s):i.isFile()&&i.name.endsWith(".md")&&e.push(s)}}return await n(t),e}function wi(t,e){let n=_.relative(e,t).split(_.sep).join("/").split("/");if(n[0]==="docs"&&(n=n.slice(1)),n.length<2)return null;let r=n[0],o=$e[r];if(o===void 0)return null;let i=n[n.length-1].replace(/\.md$/,"");return n[n.length-1]=i,{documentId:n.join("/"),catalogId:o,docTitle:i}}async function Di(t){let e=t.replace(/\.md$/,".json");try{let n=await x.promises.readFile(e,"utf-8");return JSON.parse(n).title?.trim()||void 0}catch{return}}async function Ii(t,e){let n=wi(t,e);if(!n)return[];let r=await x.promises.readFile(t,"utf-8"),o=er(r,{jsonTitle:await Di(t),fileName:n.docTitle});return ur(r,{...n,docTitle:o})}async function Ti(t,e,n){let r=_.join(e,"search.db");return await Zn(r,t,async(o,i)=>{await n?.({current:o,total:i,message:`Building search index\u2026 ${o.toLocaleString()} / ${i.toLocaleString()} segments`})}),t.length}async function Ci(t){let e=await Ai(t),n=[];for(let r of e){let o=await Ii(r,t);n.push(...o)}return n}function Ri(t,e){return{indexVersion:H,docsZipSha256:t.docsZipSha256,termsHash:t.termsHash,synonymsHash:t.synonymsHash,segmentCount:e,builtAt:Date.now(),builtBy:t.builtBy}}async function dr(t){t.lexiconDir&&$t(t.lexiconDir);try{let e=await Ci(t.docsDir);await t.onProgress?.({current:0,total:e.length,message:`Building search index\u2026 0 / ${e.length.toLocaleString()} segments`}),await x.promises.mkdir(t.tmpDir,{recursive:!0});let n=await Ti(e,t.tmpDir,t.onProgress),r=Ri(t,n);return await x.promises.writeFile(_.join(t.tmpDir,"build-meta.json"),JSON.stringify(r,null,2)),await on(t.tmpDir),r}finally{t.lexiconDir&&$t(null)}}async function mr(){return x.promises.mkdtemp(_.join(lr.tmpdir(),"deveco-docs-"))}async function Ni(t,e){try{await x.promises.rename(t,e)}catch(n){let r=n.code;if(r!=="EPERM"&&r!=="EXDEV")throw n;await x.promises.cp(t,e,{recursive:!0}),await x.promises.rm(t,{recursive:!0,force:!0})}}async function fr(t){let e=_.join(t,"docs");try{await x.promises.access(e)}catch{return}let n=new Set(["docs","docs.zip"]);for(let r of await x.promises.readdir(e,{withFileTypes:!0})){if(n.has(r.name))continue;let o=_.join(e,r.name),i=_.join(t,r.name);await x.promises.rm(i,{recursive:!0,force:!0}),await Ni(o,i)}await x.promises.rm(_.join(e,"docs"),{recursive:!0,force:!0}),await x.promises.rm(_.join(e,"docs.zip"),{force:!0}),await x.promises.rm(e,{recursive:!0,force:!0})}async function gr(t){let e=Ht();await h.promises.mkdir(T.dirname(e),{recursive:!0}),await h.promises.appendFile(e,`${new Date().toISOString()} ${t}
65
- `)}async function Bi(t){let e=v();if(!e)throw new Error("docs.zip not found");await h.promises.rm(t,{recursive:!0,force:!0}),await h.promises.mkdir(t,{recursive:!0});let n=T.resolve(t),r=new Pi(e);for(let o of r.getEntries()){let i=T.resolve(n,o.entryName);if(!Y(i,n))throw new Error(`Unsafe docs.zip entry path: ${o.entryName}`);if(o.isDirectory){await h.promises.mkdir(i,{recursive:!0});continue}await h.promises.mkdir(T.dirname(i),{recursive:!0}),await h.promises.writeFile(i,o.getData())}await fr(t)}async function Mi(){await st({mode:"write"});let t=g(),e=C(),n=await h.promises.readdir(e);for(let r of n){let o=T.join(t,r);await h.promises.rm(o,{force:!0}),await h.promises.rename(T.join(e,r),o)}await h.promises.rm(e,{recursive:!0,force:!0}),await h.promises.rm(T.join(t,"orama.dpack"),{force:!0})}async function pr(t,e,n){e?.start(n),await B({state:"installing",phase:1,phaseLabel:"Installing index",message:n}),await un(t),Tt(),e&&(e.text="Documentation index installed.")}async function ki(t,e){try{return await pr(t,e,"Installing documentation index\u2026"),await _e(e),!0}catch(n){if(qt(n))throw n}try{return await ln(),Tt(),await pr(t,e,"Retrying documentation index install\u2026"),await _e(e),!0}catch(n){if(qt(n))throw n;let r=n instanceof Error?n.message:String(n);return await gr(`Bundled index install failed; falling back to local rebuild: ${r}`),!1}}async function vi(t,e,n){let r=C(),o=await mr();await h.promises.mkdir(g(),{recursive:!0}),await h.promises.rm(r,{recursive:!0,force:!0}),n?.start("Building search index\u2026"),await B({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"});try{await Bi(o),await dr({docsDir:o,tmpDir:r,docsZipSha256:e,termsHash:yt(),synonymsHash:St(),builtBy:t.builtBy??"doc-init",onProgress:async i=>{n&&(n.text=i.message),await B({state:"indexing",current:i.current,total:i.total,message:i.message})}})}finally{await h.promises.rm(o,{recursive:!0,force:!0})}await B({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await Mi(),Tt()}async function _e(t){await B({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),t?.succeed("Documentation ready.")}async function Fi(t){let e=await te(),n=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";t?.succeed(n),await B({state:"done",message:n,error:null})}async function zi(t,e){let n=t instanceof Error?t.message:String(t);throw await B({state:"error",error:n}),await gr(`ERROR: ${n}`),e?.fail(n),t}async function Hi(){let t=g();await h.promises.mkdir(t,{recursive:!0});let e=ft();return h.existsSync(e)||await h.promises.writeFile(e,"","utf-8"),e}async function ji(){let t=await Hi();return Oi.lock(t,{stale:1800*1e3})}async function Ui(){let t=v(),e=(t?await ht(t):null)??await Kt();if(!e)throw new Error("docs.zip not found");return e}async function Zi(t,e){let n=await Ui(),r=t.force||await Sn(t.force),o=await ee(t.force);if(!r&&!o&&ne()){await Fi(e);return}!t.force&&cn(n)&&await ki(n,e)||(await vi(t,n,e),await _e(e))}var Ot=class{static async run(e={}){let n=e.background??!1,o=e.quiet??n?void 0:Li({text:"Checking documentation\u2026",color:"cyan"}),i;try{e.assumeStorageSafe||await st({mode:"write"}),i=await ji(),await Vt(hn("Starting documentation setup\u2026")),await Zi(e,o)}catch(s){if(i)return zi(s,o);throw s}finally{i&&await i()}}};var $i=process.env.DEVECO_CLI_POSTINSTALL?"postinstall":"doc-init";Ot.run({background:!0,builtBy:$i}).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 Nt from"path";import*as S from"fs";import*as Y from"path";import{homedir as gt}from"os";import*as H from"fs";import*as m from"path";function J(r){let t=m.resolve(r),e=[],n=t;for(;;)try{let i=H.realpathSync(n);return e.length===0?i:m.join(i,...e.reverse())}catch(i){if(i.code!=="ENOENT")throw i;let o=m.dirname(n);if(o===n)return t;e.push(m.basename(n)),n=o}}function P(r){let t=r.trim();return(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1).trim()),t}function K(r){let t=P(r);if(!t)throw new Error("Path must not be empty.");return J(t)}var ht="deveco-cli",W,N=class extends Error{constructor(t){super(t),this.name="CliDataDirError"}};function yt(){let r=process.env.DEVECO_CLI_DATA_DIR,e=(r===void 0||r===""?"":P(r))||Y.join(gt(),".local","share",ht);try{return K(e)}catch(n){throw new N(n instanceof Error?n.message:String(n))}}function X(){if(W!==void 0)return W;let r=yt();try{if(S.existsSync(r))return S.realpathSync(r)}catch{}return r}import mt from"crypto";import d from"fs";import z from"os";import y from"path";import St from"https";var q={devecoApiTraceUpload:"https://cn.devecostudio.huawei.com/codeGenie/cli/trace/upload"};var D=class r{static ENDPOINT=q.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"))};try{let{body:i}=await this.httpPost(r.ENDPOINT,n,Buffer.from(t,"utf8"),6e4);return r.isSuccess(i)}catch{return!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((s,p)=>{let l=St.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},v=>{let h=[];v.on("data",w=>h.push(w)),v.on("end",()=>{s({code:v.statusCode??0,body:Buffer.concat(h).toString("utf8")})})});l.on("timeout",()=>{l.destroy(new Error("request timeout"))}),l.on("error",p),l.write(n),l.end()})}};var G={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}config;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??G.identity,n=this.config.fieldNames??{},i={};for(let[o,s]of Object.entries(t)){let p=n[o]??e(o);i[p]=this.transform(s)}return i}},Z=new M({namingStrategy:G.snakeCase,fieldNames:{}});import E from"crypto";import C from"fs";import Et from"path";var L="aes-256-gcm",xt=12,Tt="deveco-cli-trace-file",bt="trace-file-secret",tt=32;function Q(r){try{let t=C.readFileSync(r,"utf8").trim();return t&&Buffer.from(t,"base64").length===tt?t:null}catch{return null}}function et(r){let t=Et.join(r,bt),e=Q(t);if(e)return j(e);let n=E.randomBytes(tt).toString("base64");try{C.mkdirSync(r,{recursive:!0});try{C.writeFileSync(t,n,{flag:"wx"})}catch{let i=Q(t);if(i)return j(i);C.writeFileSync(t,n)}}catch{}return j(n)}function j(r){return E.createHash("sha256").update(Tt).update(r).digest()}function $(r,t){let e=E.randomBytes(xt),n=E.createCipheriv(L,t,e),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o={version:1,algorithm:L,ciphertext:i.toString("base64"),iv:e.toString("base64"),authTag:n.getAuthTag().toString("base64")};return JSON.stringify(o)}function rt(r,t){let e;try{e=JSON.parse(r)}catch{return null}if(!wt(e))return r;try{let n=E.createDecipheriv(L,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 wt(r){if(!r||typeof r!="object")return!1;let t=r;return t.version===1&&t.algorithm===L&&typeof t.ciphertext=="string"&&typeof t.iv=="string"&&typeof t.authTag=="string"}import*as a from"fs";import*as A from"path";import*as _ from"os";import*as g from"path";import ce from"json5";function nt(){if(process.platform==="win32"){let r=process.env.LOCALAPPDATA??g.join(_.homedir(),"AppData","Local");return g.join(r,"devecocli-mcp-server","logs")}return process.platform==="darwin"?g.join(_.homedir(),"Library","Logs","devecocli-mcp-server"):g.join(_.homedir(),".local","share","devecocli-mcp-server","logs")}var it="mcp-server.log",Dt="mcp-server",Ct={maxSize:10*1024*1024,maxFiles:4},B=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={...Ct,...e},this.minLevel=t?"debug":"info",t?(this.mode="console",this.logDir=null,this.currentLogFile=null):(this.mode="file",this.logDir=nt(),this.currentLogFile=A.join(this.logDir,it),a.existsSync(this.logDir)||a.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 A.join(this.logDir,`${Dt}-${t}.log.${e}`)}fileExists(t){try{return a.accessSync(t,a.constants.F_OK),!0}catch{return!1}}cleanupOrphanLogFiles(){if(this.logDir)try{let t=a.readdirSync(this.logDir),e=[];for(let i of t)if(i===it||/^mcp-server-\d{4}-\d{2}-\d{2}\.log\.\d+$/.test(i)){let o=A.join(this.logDir,i),s=a.statSync(o);e.push({name:i,mtime:s.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{a.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)&&a.unlinkSync(e);for(let i=this.rotationOptions.maxFiles-1;i>=1;i--){let o=this.getRotatedFileName(t,i),s=this.getRotatedFileName(t,i+1);this.fileExists(o)&&a.renameSync(o,s)}let n=this.getRotatedFileName(t,1);a.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=a.statSync(this.currentLogFile);this.currentFileSize=t.size}else this.currentFileSize=0}catch{this.currentFileSize=0}try{this.fd=a.openSync(this.currentLogFile,"a")}catch{this.fd=null}}}closeLogFile(){if(this.fd!==null){try{a.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,p=`[${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(p);a.writeSync(this.fd,l),this.checkRotation(l.byteLength)}catch{this.closeLogFile(),this.openLogFile()}}else this.mode==="console"&&process.stderr.write(p)}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{a.fsyncSync(this.fd)}catch{}}getLogFilePath(){return this.currentLogFile}getLogDirectory(){return this.logDir}},x=null;function Lt(r=!1){x&&x.dispose(),x=new B(r)}function F(){return x||Lt(!1),x}var f={debug:(r,...t)=>F().debug(r,...t),info:(r,...t)=>F().info(r,...t),warn:(r,...t)=>F().warn(r,...t),error:(r,...t)=>F().error(r,...t)};import ot from"fs";import _t from"path";var O=300*1e3,R=3600*1e3,st=10080*60*1e3;function k(){let r=process.env.DEVECO_CLI_DISABLE_TELEMETRY;return r==="1"||r==="true"}var Ft="upload-state.json";function at(r){return _t.join(r,Ft)}function At(){return{firstEventAt:null,lastUploadAt:null,lastRetryAt:null}}function U(r){try{let t=ot.readFileSync(at(r),"utf8"),e=JSON.parse(t);return{firstEventAt:typeof e.firstEventAt=="number"?e.firstEventAt:null,lastUploadAt:typeof e.lastUploadAt=="number"?e.lastUploadAt:null,lastRetryAt:typeof e.lastRetryAt=="number"?e.lastRetryAt:null}}catch{return At()}}function V(r,t){try{ot.writeFileSync(at(r),JSON.stringify(t),"utf8")}catch{}}function lt(r){let t=U(r);t.firstEventAt===null&&(t.firstEventAt=Date.now(),V(r,t))}function ct(r){let t=U(r);t.lastUploadAt=Date.now(),t.firstEventAt=null,V(r,t)}function ut(r){let t=U(r);t.lastRetryAt=Date.now(),V(r,t)}function pt(r){let t=r.match(/^telemetry-(\d{4})-(\d{2})-(\d{2})\.txt$/);if(!t)return null;let e=Date.parse(`${t[1]}-${t[2]}-${t[3]}T00:00:00`);return Number.isFinite(e)?e:null}import Ot from"crypto";import I from"fs";import Rt from"path";var kt="install-id";function It(r){return Rt.join(r,kt)}function ft(r){try{let t=I.readFileSync(r,"utf8").trim();return Pt(t)?t:null}catch{return null}}function Pt(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 dt(r){let t=It(r),e=ft(t);if(e)return e;let n=Ot.randomUUID();try{I.mkdirSync(r,{recursive:!0});try{I.writeFileSync(t,n,{flag:"wx"})}catch{let i=ft(t);if(i)return i;I.writeFileSync(t,n)}}catch{}return n}var T=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 D;storageDir="";failedDir="";installId="";disabled=k();traceFileKey=Buffer.alloc(0);sessionId=mt.randomUUID();cliVersion="";devecoStudioVersion=null;sourceType="";cltVersion=null;nodeVersion="";initialTimer=null;intervalTimer=null;retryInitialTimer=null;retryTimer=null;flushChain=Promise.resolve();constructor(){f.info(`[telemetry] instance created, sessionId=${this.sessionId}`)}init(t){this.storageDir=t,this.failedDir=y.join(t,"failed"),this.cliVersion="1.3.1-Test.1",this.nodeVersion=process.version,this.installId=dt(t).replace(/-/g,""),this.traceFileKey=et(t),d.mkdirSync(t,{recursive:!0}),d.mkdirSync(this.failedDir,{recursive:!0}),f.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,f.info(`[telemetry] studio version set: ${t}`)}setSourceType(t){this.sourceType=t,f.info(`[telemetry] sourceType set: ${t}`)}setCltVersion(t){this.cltVersion=t,f.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(!e){await this.record(t,0,!0,null);return}if(typeof e!="function"){let o=e;await this.record(t,o.duration_ms,o.success,o.error_code);return}let n=e,i=Date.now();try{let o=await n(),s=Date.now()-i;return await this.record(t,s,!0,null),o}catch(o){let s=Date.now()-i,p=this.toErrorCode(o);throw await this.record(t,s,!1,p),o}}async record(t,e,n,i){let o=this.buildTraceEvent(t,e,n,i);try{let s=$(JSON.stringify(o),this.traceFileKey);await d.promises.appendFile(this.currentFile(),s+`
3
+ `,"utf8"),lt(this.storageDir)}catch{}}buildTraceEvent(t,e,n,i){let o=`${r.EVENT_PREFIX}${t.event}`,s=Z.toObject(t);return s&&typeof s=="object"&&delete s.event,{countryCode:r.COUNTRY_CODE,event:o,eventtime:String(Date.now()),properties:{uid:this.installId,trace_uuid:mt.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:s}}}toErrorCode(t){return t instanceof Error?t.code??t.name:"UnknownError"}resolveOsArch(){let t=z.arch();return t==="x64"?"amd64":t}resolveOsName(){switch(process.platform){case"win32":{let t=z.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 z.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 y.join(this.storageDir,`telemetry-${this.dateString()}.txt`)}startScheduler(){if(this.stopScheduler(),this.disabled){f.info("[telemetry] scheduler not started (telemetry disabled)");return}f.info(`[telemetry] scheduler started (flush every ${O/1e3}s, retry failed every ${R/1e3}s)`),this.initialTimer=setTimeout(()=>{this.flush().catch(()=>{}),this.intervalTimer=setInterval(()=>{this.flush().catch(()=>{})},O)},O),this.retryInitialTimer=setTimeout(()=>{this.retryFailed().catch(()=>{}),this.retryTimer=setInterval(()=>{this.retryFailed().catch(()=>{})},R)},R)}stopScheduler(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.intervalTimer&&(clearInterval(this.intervalTimer),this.intervalTimer=null),this.retryInitialTimer&&(clearTimeout(this.retryInitialTimer),this.retryInitialTimer=null),this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=null),f.info("[telemetry] scheduler stopped")}async flush(){return this.disabled?!0:this.runExclusive(()=>this.performFlush())}async performFlush(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");let t=await this.listPendingFiles(),e=!0;for(let n of t)await this.flushFile(n)||(e=!1);return ct(this.storageDir),e}async retryFailed(){return this.disabled?!0:this.runExclusive(()=>this.performRetryFailed())}async performRetryFailed(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");let t=Date.now(),e;try{e=await d.promises.readdir(this.failedDir)}catch{return!0}let n=e.filter(o=>o.startsWith("telemetry-")&&o.endsWith(".txt")).map(o=>y.join(this.failedDir,o)),i=!0;for(let o of n){let s=y.basename(o),p=pt(s);if(p!==null){if(t-p>st){try{await d.promises.unlink(o)}catch{}continue}await this.flushFile(o)||(i=!1)}}return i||f.warn("[telemetry] retry failed"),ut(this.storageDir),i}runExclusive(t){let e=()=>t(),n=this.flushChain.then(e,e);return this.flushChain=n.then(()=>{},()=>{}),n}async listPendingFiles(){let t;try{t=await d.promises.readdir(this.storageDir)}catch{return[]}return t.filter(e=>e.startsWith("telemetry-")&&e.endsWith(".txt")).map(e=>y.join(this.storageDir,e)).sort()}async flushFile(t){let e=t+".pending";try{await d.promises.rename(t,e)}catch{return!1}let n;try{n=await d.promises.readFile(e,"utf8")}catch{return!1}let i=n.split(`
4
+ `).map(s=>s.trim()).filter(Boolean),o=[];for(let s of i){let p=rt(s,this.traceFileKey);p!==null&&o.push(p)}if(o.length===0){try{await d.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=[],s=16;for(;n<e.length&&o.length<r.MAX_BATCH;){let h=e[n],w=Buffer.byteLength(h,"utf8")+1;if(o.length>0&&s+w>r.MAX_PAYLOAD_BYTES)break;o.push(h),s+=w,n++}let p=this.buildPayloadItems(o),l=JSON.stringify(p),v=!1;try{v=await this.uploader.upload(l,this.installId)}catch{}if(!v){f.warn("[telemetry] upload failed");let h=e.slice(i).join(`
5
+ `)+`
6
+ `;return await this.moveToFailed(t,h),!1}}try{await d.promises.unlink(t)}catch{}return!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=y.basename(t,".pending"),i=y.join(this.failedDir,n);try{let o=e.split(`
7
+ `).filter(Boolean).map(s=>$(s,this.traceFileKey)).join(`
8
+ `)+`
9
+ `;await d.promises.appendFile(i,o,"utf8")}catch{return}try{await d.promises.unlink(t)}catch{}}};var b=new T;import{spawn as Ve}from"child_process";import{existsSync as He}from"fs";import{dirname as Ke,join as We}from"path";import{fileURLToPath as Xe}from"url";var Mt=Nt.join(X(),"TraceLogData");b.init(Mt);(async()=>{try{await b.flush(),await b.retryFailed()}catch(r){f.warn("[telemetry] background upload error:",r),process.exit(1)}})();
package/docs.zip CHANGED
Binary file
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.8",
3
+ "version": "1.3.1-Test.1",
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,12 +44,14 @@
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
- "@types/yauzl": "^2.10.3",
52
47
  "@types/fs-extra": "^11.0.4",
53
48
  "@types/global-agent": "^3.0.0",
54
49
  "@types/node": "^25.6.0",
50
+ "@types/node-forge": "^1.3.14",
51
+ "@types/proper-lockfile": "^4.1.4",
52
+ "@types/semver": "^7.7.1",
55
53
  "@types/turndown": "^5.0.5",
54
+ "@types/yauzl": "^2.10.3",
56
55
  "eslint": "^10.2.1",
57
56
  "generate-license-file": "^4.2.1",
58
57
  "husky": "^9.1.7",
@@ -61,38 +60,36 @@
61
60
  "tsx": "^4.21.0",
62
61
  "turndown": "^7.2.4",
63
62
  "typescript": "^6.0.3",
64
- "@types/node-forge": "^1.3.14",
65
- "typescript-eslint": "^8.59.1"
63
+ "typescript-eslint": "^8.59.1",
64
+ "vitest": "^4.1.10"
66
65
  },
67
66
  "dependencies": {
68
67
  "@modelcontextprotocol/sdk": "^1.29.0",
69
- "@node-rs/jieba": "^2.0.1",
70
68
  "@sqlite.org/sqlite-wasm": "^3.49.1-build4",
71
- "adm-zip": "^0.5.17",
72
- "axios": "1.17.0",
69
+ "adm-zip": "0.6.0",
70
+ "axios": "1.19.0",
73
71
  "colorette": "^2.0.20",
74
72
  "commander": "^13.1.0",
75
73
  "execa": "^9.6.1",
76
74
  "fs-extra": "^11.3.4",
77
75
  "global-agent": "^4.1.3",
76
+ "jieba-wasm": "^2.4.0",
78
77
  "json5": "^2.2.3",
79
78
  "mdast-util-to-string": "^4.0.0",
79
+ "node-forge": "^1.4.0",
80
80
  "ora": "^9.4.0",
81
81
  "p-limit": "^5.0.0",
82
82
  "proper-lockfile": "^4.1.2",
83
83
  "regedit": "^5.1.4",
84
84
  "remark-gfm": "^4.0.1",
85
85
  "remark-parse": "^11.0.0",
86
+ "semver": "^7.8.5",
86
87
  "smol-toml": "^1.6.1",
88
+ "socket.io-client": "^4.7.5",
87
89
  "unified": "^11.0.5",
88
90
  "yauzl": "^3.2.0",
89
- "node-forge": "^1.4.0",
90
91
  "zod": "^4.4.3"
91
92
  },
92
- "optionalDependencies": {
93
- "better-sqlite3": "^12.11.1",
94
- "@node-rs/jieba-wasm32-wasi": "2.0.1"
95
- },
96
93
  "overrides": {
97
94
  "dotenv": "16.4.7"
98
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
- }