@microi.net/cli 5.1.9 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +6 -6
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/mcp-server.js +85 -85
- package/scripts/microi-cli.js +2 -2
- package/scripts/microi-skills.meta.json +210 -195
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +3566 -3566
- package/skills/README.md +2 -1
- package/skills/app-store/SKILL.md +3 -3
- package/skills/job-engine/SKILL.md +1 -1
- package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +1 -1
- package/skills/microi-docs-coverage/references/capability-map.md +1 -0
- package/skills/microi-left-right-layout/SKILL.md +2 -0
- package/skills/microi-sso/SKILL.md +82 -0
- package/skills/microi-sso/references/acceptance.md +49 -0
- package/skills/microi-sso/references/configuration-and-security.md +53 -0
- package/skills/microi-sso/references/inbound.md +53 -0
- package/skills/microi-sso/references/outbound.md +39 -0
- package/skills/microi-ui/SKILL.md +11 -7
- package/skills/module-engine/SKILL.md +1 -1
- package/skills/module-engine/references/module-config.md +1 -1
- package/skills/ui-design/SKILL.md +13 -9
- package/skills/v8-crud-api/SKILL.md +2 -2
- package/skills/v8-debugging/SKILL.md +3 -1
- package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +3 -2
- package/skills/v8-table-event/SKILL.md +1 -1
- package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +1 -1
package/scripts/microi-cli.js
CHANGED
|
@@ -38,7 +38,7 @@ Content-Type: application/octet-stream\r
|
|
|
38
38
|
|
|
39
39
|
`}function bt(s){let e=zt(s.currentCode),t=zt(s.remoteCode),n=zt(s.remoteVersion),r=Vs([e,t,n]),i=s.initial?r||"v1.0.0":xs(r),{header:o,body:a}=Ls(s.currentCode||""),c=`${Bs(s,i,o)}${a.replace(/^\s+/,"")}`,l=(s.changeSummary||"\u540C\u6B65 V8 \u4EE3\u7801").trim();return{code:c,version:i,changeHistory:`${i} ${l}`}}var at=class s{static getInstance(){return s._instance||(s._instance=new s),s._instance}constructor(){}get outputChannel(){return ie.channel}log(e){ie.log("\u540C\u6B65",e)}loadMeta(e){let t=R.getInstance(),n="";try{n=t.getSyncRootDir()}catch{}if(!n)return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};let r=v.join(n,e,Ye);if(!w.existsSync(r))return this.migrateFromFlatMeta(e);try{let i=JSON.parse(w.readFileSync(r,"utf-8"));if(!i||typeof i!="object"||Array.isArray(i))throw new Error("\u9876\u5C42\u5FC5\u987B\u662F JSON \u5BF9\u8C61");let o=i;return{...o,engines:o.engines||{},events:o.events||{},fields:o.fields||{},menus:o.menus||{},menuButtons:o.menuButtons||{},menuScripts:o.menuScripts||{},workflows:o.workflows||{},workflowNodeEvents:o.workflowNodeEvents||{}}}catch(i){throw new Error(`Microi \u540C\u6B65\u5143\u6570\u636E\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u4FDD\u7559\u539F\u6587\u4EF6\u5E76\u505C\u6B62\u5199\u5165\uFF1A${r}\uFF08${i instanceof Error?i.message:String(i)}\uFF09`)}}saveMeta(e,t){let n=R.getInstance();try{let r=n.getSyncRootDir();this.ensureSyncGitExcludes(r);let i=v.join(r,t);ge(i);let o=v.join(i,Ye),a=`${o}.${process.pid}.${Date.now()}.tmp`;try{w.writeFileSync(a,`${JSON.stringify(e,null,2)}
|
|
40
40
|
`,"utf-8"),w.renameSync(a,o)}finally{try{w.existsSync(a)&&w.unlinkSync(a)}catch{}}}catch{}}getWorkspaceFilePath(e){let t=R.getInstance().getWorkspaceRoot();return t?v.isAbsolute(e)?e:v.join(t,e):null}normalizeCode(e){return _e(_n(e||"")).replace(/\r\n/g,`
|
|
41
|
-
`).trimEnd()}isLocalModified(e,t){try{if(!w.existsSync(e))return!1;let n=w.statSync(e),r=new Date(t);return isNaN(r.getTime())?!1:n.mtime.getTime()>r.getTime()+1e3}catch{return!1}}getLocalModifiedTime(e,t){try{if(!w.existsSync(e))return null;let n=w.statSync(e),r=new Date(t);return isNaN(r.getTime())?null:n.mtime.getTime()>r.getTime()+1e3?we(n.mtime):null}catch{return null}}touchSyncedFile(e,t){let n=new Date(t),r=isNaN(n.getTime())?new Date:n;try{w.utimesSync(e,r,r)}catch{}}ensureSyncGitExcludes(e){try{let t=e||R.getInstance().getSyncRootDir();rt(t),xe(t,[".backups/","**/.backups/",".microi-mcp-tokens.json","**/.microi-mcp-tokens.json"])}catch{}}shortBackupKey(e){return require("crypto").createHash("sha1").update(e||"").digest("hex").slice(0,10)}getMenuButtonMetaKey(e,t,n,r){return`${e}__${t}__${n}__${r}`}getMenuScriptMetaKey(e,t){return`${e}__${t}`}sourceHash(e){return require("crypto").createHash("sha256").update(this.normalizeCode(e||"")).digest("hex")}extractTrailingKey(e){let t=e.match(/[((]([^))]+)[))]\s*$/);return t?t[1]:e}getServerDirs(){try{let e=R.getInstance().getSyncRootDir();return w.existsSync(e)?w.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).filter(t=>!t.name.startsWith(".")).map(t=>t.name):[]}catch{return[]}}getLocalChangeSummary(){let e={engines:0,events:0,fields:0,menuButtons:0,menuScripts:0,workflowNodeEvents:0,total:0};for(let t of this.getLocalChangeItems())t.kind==="engine"?e.engines+=1:t.kind==="event"?e.events+=1:t.kind==="field"?e.fields+=1:t.kind==="menuButton"?e.menuButtons+=1:t.kind==="menuScript"?e.menuScripts+=1:t.kind==="workflow"&&(e.workflowNodeEvents+=1);return e.total=e.engines+e.events+e.fields+e.menuButtons+e.menuScripts+e.workflowNodeEvents,e}getLocalChangeItems(){let e=[],t=(n,r,i,o,a)=>{let c=this.getWorkspaceFilePath(a.filePath);if(!c)return;let l=this.getLocalModifiedTime(c,a.updateTime);l&&e.push({kind:r,key:i,name:o,serverDir:n,filePath:c,updateTime:a.updateTime,modifiedTime:l})};for(let n of this.getServerDirs()){let r=this.loadMeta(n);for(let[i,o]of Object.entries(r.engines))t(n,"engine",i,o.apiName||i,o);for(let[i,o]of Object.entries(r.events))t(n,"event",i,`${o.description||o.formEngineKey}/${o.eventType}`,o);for(let[i,o]of Object.entries(r.fields||{}))t(n,"field",i,`${o.tableName}.${o.fieldName}/${o.v8Key}`,o);for(let[i,o]of Object.entries(r.menuButtons||{}))t(n,"menuButton",i,`${o.moduleName}/${o.btnName}/${o.v8SubField}`,o);for(let[i,o]of Object.entries(r.menuScripts||{}))t(n,"menuScript",i,`${o.moduleName}/${o.scriptField}`,o);for(let[i,o]of Object.entries(r.workflowNodeEvents||{}))t(n,"workflow",i,`${o.flowName}/${o.nodeName}/${o.eventType}`,o)}return e}async checkRemoteDifferences(e,t="all",n){let r=e?[e]:R.getInstance().getProfiles(),i=[];for(let o of r){let a=R.getInstance().buildServerDirName(o.label,o.apiBaseUrl),c=this.loadMeta(a),l=n?this.getTargetSyncKind(c,n):null;if(n&&!l)throw new Error(`\u540C\u6B65\u76EE\u6807\u4E0D\u5728\u672C\u5730\u57FA\u7EBF\u4E2D: ${n}`);(t==="all"||t==="api")&&(!n||l==="engine")&&await this.collectEngineDifferences(o,a,c,i,n),(t==="all"||t==="form")&&(!n||l==="event")&&await this.collectEventDifferences(o,a,c,i,n),(t==="all"||t==="form")&&(!n||l==="field")&&await this.collectFieldDifferences(o,a,c,i,n),(t==="all"||t==="module")&&(!n||l==="menuButton")&&await this.collectMenuButtonDifferences(o,a,c,i,n),(t==="all"||t==="module")&&(!n||l==="menuScript")&&await this.collectMenuScriptDifferences(o,a,c,i,n),(t==="all"||t==="workflow")&&(!n||l==="workflow")&&await this.collectWorkflowDifferences(o,a,c,i,n)}return i}matchesTargetFile(e,t){if(!t)return!0;let n=this.getWorkspaceFilePath(e);return!!n&&v.resolve(n).toLowerCase()===v.resolve(t).toLowerCase()}getTargetSyncKind(e,t){let n=[["engine",e.engines],["event",e.events],["field",e.fields||{}],["menuButton",e.menuButtons||{}],["menuScript",e.menuScripts||{}],["workflow",e.workflowNodeEvents||{}]];for(let[r,i]of n)if(Object.values(i).some(o=>this.matchesTargetFile(o.filePath,t)))return r;return null}classifyDifference(e,t,n,r){return n===r?null:e&&t?"conflict":e?"localModified":"remoteModified"}classifyRemoteDeletion(e,t){return this.isLocalModified(e,t)?"conflict":"remoteDeleted"}createRemoteDeletedItem(e,t,n,r,i,o){return!i||!w.existsSync(i)?null:{kind:e,status:this.classifyRemoteDeletion(i,o),name:t,key:n,serverDir:r,filePath:i,localCode:this.normalizeCode(w.readFileSync(i,"utf-8")),remoteCode:"",localUpdateTime:o,remoteUpdateTime:""}}isRemoteNewer(e,t){let n=new Date(e||"").getTime(),r=new Date(t||"").getTime();return isNaN(n)||isNaN(r)?!1:n>r+1e3}getRemoteOnlyPlaceholderPath(e,t,n,r){let i=R.getInstance(),o=n==="api"?Xe:n==="form"?Ve:n==="module"?je:Ze;return v.join(i.getSyncRootDir(),t,i.buildOsClientDirName(e.osClient,e.osClientType,e.osClientNetwork),o,"\u670D\u52A1\u5668\u65B0\u589E\u5F85\u62C9\u53D6",`${q(r)}.js`)}async collectEngineDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_ENGINE_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u63A5\u53E3\u5F15\u64CE\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map(a.Data.List.map(u=>[u.ApiEngineKey,u])),l=!1;for(let[u,d]of Object.entries(n.engines)){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g){let T=this.createRemoteDeletedItem("engine",d.apiName||u,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.ApiV8Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);C&&r.push({kind:"engine",status:C,name:g.ApiName||d.apiName||u,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.engines).map(u=>u.toLowerCase()));for(let u of a.Data.List)!String(u.ApiV8Code||"").trim()||p.has(u.ApiEngineKey.toLowerCase())||r.push({kind:"engine",status:"remoteModified",name:u.ApiName||u.ApiEngineKey,key:u.ApiEngineKey,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"api",u.ApiEngineKey),localCode:"",remoteCode:this.normalizeCode(u.ApiV8Code||""),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}async collectEventDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_EVENT_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u8868\u5355\u4E8B\u4EF6\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map;for(let u of a.Data.List){let d=`${u.FormEngineKey}__${u.EventType}`;c.set(d,u),c.set(d.toLowerCase(),u)}let l=!1;for(let[u,d]of Object.entries(n.events)){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u)||c.get(u.toLowerCase()),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g){let T=this.createRemoteDeletedItem("event",`${d.description||d.formEngineKey}/${d.eventType}`,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.V8Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);C&&r.push({kind:"event",status:C,name:`${g.Description||d.formEngineKey}/${d.eventType}`,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.events).map(u=>u.toLowerCase()));for(let u of a.Data.List){let d=`${u.FormEngineKey}__${u.EventType}`;!String(u.V8Code||"").trim()||p.has(d.toLowerCase())||r.push({kind:"event",status:"remoteModified",name:`${u.Description||u.FormEngineKey}/${u.EventType}`,key:d,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"form",d),localCode:"",remoteCode:this.normalizeCode(u.V8Code||""),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}}async collectFieldDifferences(e,t,n,r,i){let o=j.getInstance(),a=new Map;for(let l of Object.entries(n.fields||{})){if(!this.matchesTargetFile(l[1].filePath,i))continue;let p=a.get(l[1].tableId||l[1].tableName)||[];p.push(l),a.set(l[1].tableId||l[1].tableName,p)}let c=!1;await this.runInBatches([...a.values()],i?1:2,async l=>{let p=l[0][1],u=await o.get(K.GET_FIELD_LIST,{osClient:e.osClient,tableId:p.tableId,tableName:p.tableName},e.apiBaseUrl,e);if(u.Code!==1||!Array.isArray(u.Data?.List))throw new Error(`\u83B7\u53D6\u5B57\u6BB5\u540C\u6B65\u72B6\u6001\u5931\u8D25[${p.tableName}]: ${u.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let d=new Map(u.Data.List.map(g=>[String(g.Name||"").toLowerCase(),g]));for(let[g,m]of l){let y=d.get(m.fieldName.toLowerCase()),f=this.getWorkspaceFilePath(m.filePath);if(!f||!w.existsSync(f))continue;if(!y||!String(y[m.v8Key]||"").trim()){let b=this.createRemoteDeletedItem("field",`${m.tableName}.${m.fieldName}/${m.v8Key}`,g,t,f,m.updateTime);b&&r.push(b);continue}let h=this.normalizeCode(w.readFileSync(f,"utf-8")),S=this.normalizeCode(String(y[m.v8Key]||"")),C=String(y.UpdateTime||""),T=this.isLocalModified(f,m.updateTime),k=this.isRemoteNewer(C,m.updateTime);if(h===S){(T||k)&&C&&(m.updateTime=C,this.touchSyncedFile(f,C),c=!0);continue}let E=this.classifyDifference(T,k,h,S);E&&r.push({kind:"field",status:E,name:`${m.tableName}.${m.fieldName}/${m.v8Key}`,key:g,serverDir:t,filePath:f,localCode:h,remoteCode:S,localUpdateTime:m.updateTime,remoteUpdateTime:C})}}),c&&this.saveMeta(n,t)}async collectMenuButtonDifferences(e,t,n,r,i){let o=j.getInstance(),a=new Map;if(!i)for(let d of Object.keys(n.menus||{}))a.set(d,[]);for(let d of Object.entries(n.menuButtons||{})){if(!this.matchesTargetFile(d[1].filePath,i))continue;let g=a.get(d[1].moduleId)||[];g.push(d),a.set(d[1].moduleId,g)}let c=[];if(!i){let d=await o.get(K.LIST_MODULES,{osClient:e.osClient},e.apiBaseUrl,e);if(d.Code!==1||!Array.isArray(d.Data?.List))throw new Error(`\u83B7\u53D6\u6A21\u5757\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${d.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);c=d.Data.List}let l=new Set(c.map(d=>String(d.ParentId||"")).filter(Boolean)),p=new Map(c.map(d=>[d.Id,d]));for(let d of c){if(l.has(d.Id)||n.menus?.[d.Id])continue;let g=d.Label||d.Name||d.Id;r.push({kind:"menuButton",status:"remoteModified",name:`${g}/\u670D\u52A1\u5668\u65B0\u589E\u6A21\u5757`,key:d.Id,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"module",d.Id),localCode:"",remoteCode:JSON.stringify(d,null,2),localUpdateTime:"",remoteUpdateTime:String(d.UpdateTime||"")})}let u=!1;await this.runInBatches([...a.entries()],i?1:2,async([d,g])=>{let m=()=>{for(let[k,E]of g){let b=this.getWorkspaceFilePath(E.filePath);if(!b)continue;let V=this.createRemoteDeletedItem("menuButton",`${E.moduleName}/${E.btnName}/${E.v8SubField}`,k,t,b,E.updateTime);V&&r.push(V)}};if(!i&&!p.has(d)){m();return}let y=await o.get(K.GET_MODULE,{osClient:e.osClient,moduleId:d},e.apiBaseUrl,e);if(y.Code!==1||!y.Data){if(/不存在|not\s*found/i.test(String(y.Msg||""))){m();return}throw new Error(`\u83B7\u53D6\u6A21\u5757\u6309\u94AE\u540C\u6B65\u72B6\u6001\u5931\u8D25[${d}]: ${y.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`)}let f=y.Data,h=String(f.UpdateTime||""),S=new Map;for(let k of Object.keys(et)){let E=[];try{let b=f[k];E=typeof b=="string"?JSON.parse(b):Array.isArray(b)?b:[],Array.isArray(E)||(E=[])}catch{E=[]}S.set(k,new Map(E.map(b=>[String(b.Id||""),b])))}for(let[k,E]of g){let b=S.get(E.btnField)?.get(E.btnId),V=this.getWorkspaceFilePath(E.filePath);if(!V||!w.existsSync(V))continue;if(!b||!String(b[E.v8SubField]||"").trim()){let D=this.createRemoteDeletedItem("menuButton",`${E.moduleName}/${E.btnName}/${E.v8SubField}`,k,t,V,E.updateTime);D&&r.push(D);continue}let z=this.normalizeCode(w.readFileSync(V,"utf-8")),F=this.normalizeCode(String(b[E.v8SubField]||"")),I=this.isLocalModified(V,E.updateTime),x=this.isRemoteNewer(h,E.updateTime);if(z===F){(I||x)&&h&&(E.updateTime=h,this.touchSyncedFile(V,h),u=!0);continue}let A=this.classifyDifference(I,x,z,F);A&&r.push({kind:"menuButton",status:A,name:`${E.moduleName}/${E.btnName}/${E.v8SubField}`,key:k,serverDir:t,filePath:V,localCode:z,remoteCode:F,localUpdateTime:E.updateTime,remoteUpdateTime:h})}if(i)return;let C=new Set(g.map(([k])=>k)),T=n.menus?.[d]?.moduleName||p.get(d)?.Label||p.get(d)?.Name||d;for(let[k,E]of S)for(let[b,V]of E){if(!b)continue;let z=String(V.Name||b);for(let F of["V8Code","V8CodeShow"]){let I=String(V[F]||""),x=this.getMenuButtonMetaKey(d,k,b,F);!I.trim()||C.has(x)||r.push({kind:"menuButton",status:"remoteModified",name:`${T}/${z}/${F}`,key:x,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"module",x),localCode:"",remoteCode:this.normalizeCode(I),localUpdateTime:"",remoteUpdateTime:h})}}}),u&&this.saveMeta(n,t)}async collectMenuScriptDifferences(e,t,n,r,i){let o=j.getInstance(),a=Object.entries(n.menuScripts||{}).filter(([,l])=>this.matchesTargetFile(l.filePath,i)),c=!1;await this.runInBatches(a,i?1:2,async([l,p])=>{let u=this.getWorkspaceFilePath(p.filePath);if(!u||!w.existsSync(u))return;let d=await o.get(K.GET_MODULE,{osClient:e.osClient,moduleId:p.moduleId},e.apiBaseUrl,e);if(d.Code!==1||!d.Data){if(/不存在|not\s*found/i.test(String(d.Msg||""))){let T=this.createRemoteDeletedItem("menuScript",`${p.moduleName}/${p.scriptField}`,l,t,u,p.updateTime);T&&r.push(T);return}throw new Error(`\u83B7\u53D6\u6A21\u5757 Join/Where \u540C\u6B65\u72B6\u6001\u5931\u8D25[${p.moduleId}]: ${d.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`)}let g=d.Data,m=this.normalizeCode(String(g[p.scriptField]||"")),y=this.normalizeCode(w.readFileSync(u,"utf-8")),f=String(g.UpdateTime||""),h=this.isLocalModified(u,p.updateTime),S=this.sourceHash(m)!==p.codeHash;if(y===m){(h||S||f&&f!==p.updateTime)&&(p.codeHash=this.sourceHash(m),p.updateTime=f||p.updateTime,this.touchSyncedFile(u,p.updateTime),c=!0);return}let C=this.classifyDifference(h,S,y,m);C&&r.push({kind:"menuScript",status:C,name:`${p.moduleName}/${p.scriptField}`,key:l,serverDir:t,filePath:u,localCode:y,remoteCode:m,localUpdateTime:p.updateTime,remoteUpdateTime:f})}),c&&this.saveMeta(n,t)}async runInBatches(e,t,n){for(let r=0;r<e.length;r+=t)await Promise.all(e.slice(r,r+t).map(i=>n(i))),r+t<e.length&&await new Promise(i=>setTimeout(i,120))}async collectWorkflowDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_WORKFLOW_V8_EVENT_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u6D41\u7A0B\u4E8B\u4EF6\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map(a.Data.List.map(u=>[`${u.FlowDesignId}__${u.NodeId}__${u.EventType}`,u])),l=!1;for(let[u,d]of Object.entries(n.workflowNodeEvents||{})){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g||!String(g.V8Code||g.Code||"").trim()){let T=this.createRemoteDeletedItem("workflow",`${d.flowName}/${d.nodeName}/${d.eventType}`,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.V8Code||g.Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);if(C){let T=`${g.FlowName||d.flowName}/${g.NodeName||d.nodeName}/${g.EventType||d.eventType}`;r.push({kind:"workflow",status:C,name:T,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.workflowNodeEvents||{}));for(let u of a.Data.List){let d=`${u.FlowDesignId}__${u.NodeId}__${u.EventType}`,g=u.V8Code||u.Code||"";if(!g.trim()||p.has(d))continue;let m=`${u.FlowName||u.FlowDesignId}/${u.NodeName||u.NodeId}/${u.EventType}`;r.push({kind:"workflow",status:"remoteModified",name:m,key:d,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"workflow",d),localCode:"",remoteCode:this.normalizeCode(g),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}}migrateFromFlatMeta(e){let t=R.getInstance();try{let n=t.getSyncRootDir(),r=v.join(n,Ye);if(!w.existsSync(r))return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};let i=t.getWorkspaceRoot();if(!i)return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};let o=JSON.parse(w.readFileSync(r,"utf-8")),a=o.engines||{},c=o.events||{},l={engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};for(let[p,u]of Object.entries(a)){let d=u;if(d.filePath){let g=v.join(i,d.filePath);v.relative(n,g).split(v.sep)[0]===e&&(l.engines[p]=d)}}for(let[p,u]of Object.entries(c)){let d=u;if(d.filePath){let g=v.join(i,d.filePath);v.relative(n,g).split(v.sep)[0]===e&&(l.events[p]=d)}}return(Object.keys(l.engines).length>0||Object.keys(l.events).length>0)&&this.saveMeta(l,e),l}catch{return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}}}}async pullEngines(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0){M.warn("Microi: \u6CA1\u6709\u5DF2\u8FDE\u63A5\u7684\u670D\u52A1\u5668\uFF0C\u8BF7\u5148\u5728\u8BBE\u7F6E\u4E2D\u6DFB\u52A0\u8FDE\u63A5\u5E76\u767B\u5F55");return}for(let n of t)try{await this.pullEnginesForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`),M.error(`Microi: \u62C9\u53D6 [${n.label||n.apiBaseUrl}] \u5931\u8D25 - ${i}`)}return}await this.pullEnginesForProfile(e)}async pullEnginesForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE\u4EE3\u7801 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u63A5\u53E3\u5F15\u64CE [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u68C0\u67E5\u540E\u7AEF\u72B6\u6001..."});let a=await n.get(K.GET_STATUS,void 0,r,e);if(a.Code!==1){let A=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u540E\u7AEF\u72B6\u6001\u5F02\u5E38: ${a.Msg||"Code="+a.Code}${A}`)}o.report({message:"\u83B7\u53D6\u7CFB\u7EDF\u914D\u7F6E..."});let l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u}),o.report({message:"\u83B7\u53D6\u63A5\u53E3\u5F15\u64CE\u5217\u8868..."});let g=await n.get(K.GET_ENGINE_LIST,{osClient:i},r,e);if(g.Code!==1){let A=g.Code===1001||g.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u5217\u8868\u5931\u8D25: ${g.Msg||"Code="+g.Code}${A}`)}let{OsClient:m,OsClientType:y,OsClientNetwork:f,List:h,Total:S}=g.Data;if(this.log(`\u83B7\u53D6\u5230 ${S} \u4E2A\u63A5\u53E3\u5F15\u64CE (OsClient: ${m})`),!y||!f)throw new Error(`\u540E\u7AEF\u672A\u8FD4\u56DE\u5B8C\u6574\u7684 OsClientType/OsClientNetwork (OsClient: ${m}, Type: ${y||"\u7A7A"}, Network: ${f||"\u7A7A"})\uFF0C\u65E0\u6CD5\u62C9\u53D6\u4EE3\u7801`);if(y||f){let A={...e,osClientType:y,osClientNetwork:f};await t.addProfile(A)}let C=t.getSyncRootDir(),T=t.buildServerDirName(d,r),k=this.loadMeta(T),E=0,b=0,V=[],z=new Set,F=new Set,I=t.buildOsClientDirName(m,y,f);for(let A of h)try{let D=q(A.Category||"\u672A\u5206\u7C7B"),O=q(A.ApiName||A.ApiEngineKey),J=v.join(C,T,I,Xe,D),Y=q(`${O}(${In(A.ApiEngineKey)}).js`),ue=v.join(J,Y),pe=_n(A.ApiV8Code||"");if(!pe.trim()){b++,w.existsSync(ue)&&this.backupAndDeleteSyncFile(ue,T,"remote-deleted-api"),delete k.engines[A.ApiEngineKey];continue}z.add(A.ApiEngineKey),ge(J),w.writeFileSync(ue,pe,"utf-8");let te=new Date(A.UpdateTime);isNaN(te.getTime())||w.utimesSync(ue,te,te),k.engines[A.ApiEngineKey]={id:A.Id,apiName:A.ApiName,category:D,apiAddress:A.ApiAddress,updateTime:A.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),ue)},E++,o.report({message:`${E}/${S} ${A.ApiEngineKey}`,increment:1/S*100})}catch(D){let O=D instanceof Error?D.message:String(D);F.add(A.ApiEngineKey),V.push(`${A.ApiEngineKey}: ${O}`),this.log(`\u63A5\u53E3\u5F15\u64CE\u6587\u4EF6\u5199\u5165\u5931\u8D25\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u9879 [${A.ApiEngineKey}]: ${O}`)}for(let[A,D]of Object.entries(k.engines)){if(z.has(A)||F.has(A))continue;let O=this.getWorkspaceFilePath(D.filePath);O&&this.backupAndDeleteSyncFile(O,T,"remote-deleted-api"),delete k.engines[A]}this.saveMeta(k,T);let x=d||e.label||r;this.log(`[${x}] \u62C9\u53D6\u5B8C\u6210: ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${b} \u9879\uFF0C\u5931\u8D25 ${V.length} \u9879`),V.length>0?M.warn(`Microi: [${x}] \u5DF2\u62C9\u53D6 ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE\uFF0C${V.length} \u4E2A\u6587\u4EF6\u5931\u8D25\uFF1B\u5931\u8D25\u660E\u7EC6\u5DF2\u5199\u5165 Microi \u8F93\u51FA\u3002`):M.info(`Microi: [${x}] \u6210\u529F\u62C9\u53D6 ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE${b>0?`\uFF08\u8DF3\u8FC7 ${b} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)})}async pullEvents(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0)return;for(let n of t)try{await this.pullEventsForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6V8\u4E8B\u4EF6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`)}return}await this.pullEventsForProfile(e)}async pullEventsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6V8\u4E8B\u4EF6\u4EE3\u7801 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6V8\u4E8B\u4EF6 [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6V8\u4E8B\u4EF6\u5217\u8868..."});let a=await n.get(K.GET_EVENT_LIST,{osClient:i},r,e);if(a.Code!==1){let I=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6V8\u4E8B\u4EF6\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}${I}`)}let{List:c,Total:l}=a.Data;this.log(`\u83B7\u53D6\u5230 ${l} \u4E2AV8\u4E8B\u4EF6`);let u=await Ce.getInstance().getSysConfig(r,i),d=u?.SysShortTitle||"",g=u?.SysTitle||"",m=d||g||u?.CompanyName||e.label||"";m&&(m!==e.label||d!==e.sysShortTitle||g!==e.sysTitle)&&await t.addProfile({...e,label:m,sysShortTitle:d,sysTitle:g});let y=t.getSyncRootDir(),f=t.buildServerDirName(m,r),h=this.loadMeta(f),S=0,C=0,T=0,k=new Set(c.map(I=>`${I.FormEngineKey}__${I.EventType}`)),b=t.getProfiles().find(I=>I.apiBaseUrl===e.apiBaseUrl&&I.osClient===e.osClient)||e;if(!b.osClientType||!b.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE\u4EE5\u83B7\u53D6\u5B8C\u6574\u914D\u7F6E");let V=t.buildOsClientDirName(i,b.osClientType,b.osClientNetwork),z={SubmitBeforeServerV8:"\u540E\u7AEF\u63D0\u4EA4\u524DV8\u4E8B\u4EF6",SubmitAfterServerV8:"\u540E\u7AEF\u63D0\u4EA4\u540EV8\u4E8B\u4EF6",SubmitFormV8:"\u524D\u7AEF\u8868\u5355\u63D0\u4EA4V8\u4E8B\u4EF6",OutFormV8:"\u524D\u7AEF\u8868\u5355\u9000\u51FAV8\u4E8B\u4EF6",ServerDataV8:"\u540E\u7AEF\u6570\u636EV8\u4E8B\u4EF6"};for(let I of c){let x=I.V8Code||"",A=q(I.Description?`${I.Description}\uFF08${I.FormEngineKey}\uFF09`:I.FormEngineKey),D=or[I.EventType]||I.EventType,O=q(`${D}\uFF08${I.EventType}\uFF09`)+".js",J=v.join(y,f,V,Ve,A,$t);ge(J);let Y=v.join(J,O),ue=z[I.EventType];if(ue){let he=q(`${ue}\uFF08${I.EventType}\uFF09`)+".js",le=v.join(J,he);le!==Y&&w.existsSync(le)&&!this.isLocalModified(le,I.UpdateTime)&&(w.existsSync(Y)?w.unlinkSync(le):w.renameSync(le,Y))}let pe=`${I.FormEngineKey}__${I.EventType}`;if(h.events[pe]={id:I.Id,formEngineKey:I.FormEngineKey,description:I.Description||"",eventType:I.EventType,updateTime:I.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),Y)},!x.trim()){w.existsSync(Y)&&this.backupAndDeleteSyncFile(Y,f,"remote-deleted-form-event"),T++,S++,o.report({message:`${S}/${l}`,increment:l>0?1/l*100:void 0});continue}w.writeFileSync(Y,x,"utf-8");let te=new Date(I.UpdateTime);isNaN(te.getTime())||w.utimesSync(Y,te,te),C++,S++,o.report({message:`${S}/${l}`,increment:l>0?1/l*100:void 0})}for(let[I,x]of Object.entries(h.events)){if(k.has(I))continue;let A=this.getWorkspaceFilePath(x.filePath);A&&this.backupAndDeleteSyncFile(A,f,"remote-deleted-form-event"),delete h.events[I]}this.saveMeta(h,f);let F=m||e.label||r;this.log(`[${F}] \u62C9\u53D6\u5B8C\u6210: ${C} \u4E2AV8\u4E8B\u4EF6\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${T} \u9879`),M.info(`Microi: [${F}] \u6210\u529F\u62C9\u53D6 ${C} \u4E2AV8\u4E8B\u4EF6\u6587\u4EF6${T>0?`\uFF08\u8DF3\u8FC7 ${T} \u4E2A\u7A7A\u4EE3\u7801\u4E8B\u4EF6\uFF09`:""}`)})}async pullWorkflows(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0)return;for(let n of t)try{await this.pullWorkflowsForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`)}return}await this.pullWorkflowsForProfile(e)}async pullWorkflowsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE\u8282\u70B9 V8 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6\u6D41\u7A0B\u8282\u70B9V8\u5217\u8868..."});let a=await n.get(K.GET_WORKFLOW_V8_EVENT_LIST,{osClient:i},r,e);if(a.Code!==1){let D=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u6D41\u7A0B\u8282\u70B9V8\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}${D}`)}let l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u});let m=t.getProfiles().find(D=>D.apiBaseUrl===e.apiBaseUrl&&D.osClient===e.osClient)||e;if(!m.osClientType||!m.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let y=a.Data.OsClient||i,f=t.buildServerDirName(d,r),h=t.buildOsClientDirName(y,m.osClientType,m.osClientNetwork),S=t.getSyncRootDir(),C=this.loadMeta(f);C.workflows||(C.workflows={}),C.workflowNodeEvents||(C.workflowNodeEvents={});let T=a.Data.Flows||[],k=a.Data.Nodes||[],E=a.Data.Lines||[],b=a.Data.List||[],V=new Map(T.map(D=>[String(D.Id||""),D])),z=new Set(T.map(D=>String(D.Id||"")).filter(Boolean)),F=new Set(b.filter(D=>String(D.V8Code||D.Code||"").trim()).map(D=>`${D.FlowDesignId}__${D.NodeId}__${D.EventType}`)),I=0,x=0;for(let D of T){let O=String(D.Id||"");if(!O)continue;let J=String(D.FlowName||O),Y=String(D.UpdateTime||we()),ue=v.join(S,f,h,Ze,q(`${J}\uFF08${O}\uFF09`));ge(ue);let pe=k.filter(le=>String(le.FlowDesignId||"")===O),te=E.filter(le=>String(le.FlowDesignId||"")===O),he=v.join(ue,"\u6D41\u7A0B\u8BBE\u8BA1\u56FE\uFF08WF_FlowDesign\uFF09.json");w.writeFileSync(he,JSON.stringify({FlowDesign:D,Nodes:pe,Lines:te},null,2),"utf-8"),this.touchSyncedFile(he,Y),C.workflows[O]={flowDesignId:O,flowName:J,updateTime:Y,filePath:v.relative(t.getWorkspaceRoot(),he)}}for(let D of b){let O=String(D.FlowDesignId||""),J=String(D.NodeId||""),Y=String(D.EventType||"");if(!O||!J||!Y)continue;let ue=V.get(O),pe=String(D.FlowName||ue?.FlowName||O),te=String(D.NodeName||J),he=ar[Y]||D.EventName||Y,le=v.join(S,f,h,Ze,q(`${pe}\uFF08${O}\uFF09`),Lt,q(`${te}\uFF08${J}\uFF09`));ge(le);let N=v.join(le,q(`${he}\uFF08${Y}\uFF09`)+".js"),me=D.V8Code||D.Code||"",se=String(D.UpdateTime||ue?.UpdateTime||we());if(C.workflowNodeEvents[`${O}__${J}__${Y}`]={flowDesignId:O,flowName:pe,nodeId:J,nodeName:te,eventType:Y,updateTime:se,filePath:v.relative(t.getWorkspaceRoot(),N)},!me.trim()){w.existsSync(N)&&this.backupAndDeleteSyncFile(N,f,"remote-deleted-workflow-event"),x++,o.report({message:`${I}/${b.length} ${pe}/${te}`});continue}w.writeFileSync(N,me,"utf-8"),this.touchSyncedFile(N,se),I++,o.report({message:`${I}/${b.length} ${pe}/${te}`})}for(let[D,O]of Object.entries(C.workflowNodeEvents)){if(F.has(D))continue;let J=this.getWorkspaceFilePath(O.filePath);J&&this.backupAndDeleteSyncFile(J,f,"remote-deleted-workflow-event"),delete C.workflowNodeEvents[D]}for(let[D,O]of Object.entries(C.workflows)){if(z.has(D))continue;let J=this.getWorkspaceFilePath(O.filePath);J&&this.backupAndDeleteSyncFile(J,f,"remote-deleted-workflow"),delete C.workflows[D]}this.saveMeta(C,f);let A=d||e.label||r;this.log(`[${A}] \u6D41\u7A0B\u5F15\u64CE\u62C9\u53D6\u5B8C\u6210: ${T.length} \u4E2A\u6D41\u7A0B\uFF0C${I} \u4E2A\u8282\u70B9V8\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${x} \u9879`),M.info(`Microi: [${A}] \u6210\u529F\u62C9\u53D6 ${T.length} \u4E2A\u6D41\u7A0B\u3001${I} \u4E2A\u6D41\u7A0B\u8282\u70B9V8\u6587\u4EF6${x>0?`\uFF08\u8DF3\u8FC7 ${x} \u4E2A\u7A7A\u4EE3\u7801\u4E8B\u4EF6\uFF09`:""}`)})}findProfileByServerDir(e){let t=R.getInstance(),n=t.getProfiles();for(let r of n)if(t.buildServerDirName(r.label,r.apiBaseUrl)===e)return r}hasSyncBaseline(e,t){let n=v.resolve(e).toLowerCase(),r=this.loadMeta(t);return[r.engines,r.events,r.fields||{},r.menuButtons||{},r.menuScripts||{},r.workflowNodeEvents||{}].some(o=>Object.values(o).some(a=>{let c=this.getWorkspaceFilePath(a.filePath);return!!c&&v.resolve(c).toLowerCase()===n}))}async runPushPreflight(e,t,n,r){if(!n){let i=`\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u6240\u5C5E\u670D\u52A1\u5668\u914D\u7F6E\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\uFF1A${e}`;return this.log(i),M.error(`Microi: ${i}`),!1}if(!this.hasSyncBaseline(e,t)){let i=`\u6587\u4EF6\u6CA1\u6709\u540C\u6B65\u57FA\u7EBF\uFF0C\u65E0\u6CD5\u786E\u8BA4\u670D\u52A1\u5668\u7AEF\u662F\u5426\u66F4\u65B0\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u3002\u8BF7\u5148\u62C9\u53D6\u5BF9\u5E94\u5F15\u64CE\uFF1A${e}`;return this.log(i),M.error(`Microi: ${i}`),!1}try{let i=await this.checkRemoteDifferences(n,r,e),o=v.resolve(e).toLowerCase(),a=i.find(p=>v.resolve(p.filePath).toLowerCase()===o);if(!a||a.status==="localModified")return!0;let l=`${a.status==="conflict"?"\u672C\u5730\u4E0E\u670D\u52A1\u5668\u5747\u5DF2\u4FEE\u6539":a.status==="remoteDeleted"?"\u670D\u52A1\u5668\u7AEF\u8D44\u6E90\u5DF2\u5220\u9664":"\u670D\u52A1\u5668\u4EE3\u7801\u8F83\u65B0"}\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u4EE5\u907F\u514D\u8986\u76D6\u3002\u8BF7\u5728\u201C\u540C\u6B65\u7ED3\u679C\u201D\u4E2D\u67E5\u770B\u5DEE\u5F02\u5E76\u62C9\u53D6\u6216\u5408\u5E76\uFF1A${a.name}`;return this.log(l),M.error(`Microi: ${l}`),!1}catch(i){let o=i instanceof Error?i.message:String(i);return this.log(`\u63A8\u9001\u524D\u540C\u6B65\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\uFF1A${o}`),M.error(`Microi: \u63A8\u9001\u524D\u540C\u6B65\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001 - ${o}`),!1}}async pushFile(e,t={}){let r=R.getInstance().getSyncRootDir();if(v.extname(e).toLowerCase()===".js"&&w.existsSync(e)){let u=yr(_e(w.readFileSync(e,"utf-8")));if(u.length>0){let d=u[0],g=`\u68C0\u6D4B\u5230 AI/\u7EC8\u7AEF\u5DE5\u5177\u8F93\u51FA\u6C61\u67D3\uFF08\u7B2C ${d.line} \u884C: ${d.marker}\uFF09\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u3002\u8BF7\u6062\u590D\u5B8C\u6574\u6E90\u7801\u540E\u518D\u8BD5\uFF1A${e}`;return this.log(g),M.error(`Microi: ${g}`),!1}}let i=gr(e,r);if(i){let u=this.findProfileByServerDir(i.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,i.serverDir,u,"api")?!1:this.pushEngineFile(e,i,u)}let o=pr(e,r);if(o){let u=this.findProfileByServerDir(o.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,o.serverDir,u,"form")?!1:this.pushEventFile(e,o,u)}let a=mr(e,r);if(a){let u=this.findProfileByServerDir(a.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,a.serverDir,u,"form")?!1:this.pushFieldFile(e,a,u)}let c=fr(e,r);if(c){let u=this.findProfileByServerDir(c.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,c.serverDir,u,"module")?!1:this.pushMenuButtonFile(e,c,u)}let l=hr(e,r);if(l){let u=this.findProfileByServerDir(l.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,l.serverDir,u,"module")?!1:this.pushMenuScriptFile(e,l,u)}let p=Sr(e,r);if(p){let u=this.findProfileByServerDir(p.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,p.serverDir,u,"workflow")?!1:this.pushWorkflowNodeFile(e,p,u)}return this.log(`\u65E0\u6CD5\u89E3\u6790\u6587\u4EF6\u8DEF\u5F84: ${e}`),!1}async pushEngineFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001\u63A5\u53E3\u5F15\u64CE: ${t.apiEngineKey}...`);try{let a="",c="";try{let g=await r.post(K.GET_ENGINE_CODE,{OsClient:t.osClient,ApiEngineKey:t.apiEngineKey},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.ApiV8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"ApiEngine",key:t.apiEngineKey,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001\u63A5\u53E3\u5F15\u64CE ${t.apiEngineKey}`}),u={OsClient:t.osClient,ApiEngineKey:t.apiEngineKey,ApiV8CodeBase64:Buffer.from(p.code,"utf8").toString("base64")};l||(u.Version=p.version,u.ChangeHistory=p.changeHistory);let d=await r.post(K.UPDATE_ENGINE_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.apiEngineKey}`);let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir);if(l?delete m.engines[t.apiEngineKey]:m.engines[t.apiEngineKey]&&(m.engines[t.apiEngineKey].updateTime=g),this.saveMeta(m,t.serverDir),l)w.existsSync(e)&&w.unlinkSync(e);else{w.writeFileSync(e,p.code,"utf-8");let y=new Date(g);isNaN(y.getTime())||w.utimesSync(e,y,y)}return!0}else return this.log(`\u63A8\u9001\u5931\u8D25: ${t.apiEngineKey} - ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u5F02\u5E38: ${t.apiEngineKey} - ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async pushEventFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001V8\u4E8B\u4EF6: ${t.formEngineKey}/${t.eventType}...`);try{let a="",c="";try{let g=await r.post(K.GET_EVENT_CODE,{OsClient:t.osClient,FormEngineKey:t.formEngineKey,EventType:t.eventType},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.V8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"V8Event",key:t.formEngineKey,eventType:t.eventType,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001 V8 \u4E8B\u4EF6 ${t.formEngineKey}/${t.eventType}`}),u={OsClient:t.osClient,FormEngineKey:t.formEngineKey,EventType:t.eventType,V8Code:p.code};l||(u.Version=p.version,u.ChangeHistory=p.changeHistory);let d=await r.post(K.UPDATE_EVENT_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.formEngineKey}/${t.eventType}`);let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir),y=`${t.formEngineKey}__${t.eventType}`;if(l)delete m.events[y];else{let f=m.events[y];m.events[y]={id:f?.id||"",formEngineKey:t.formEngineKey,description:f?.description||"",eventType:t.eventType,updateTime:g,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}}if(this.saveMeta(m,t.serverDir),l)w.existsSync(e)&&w.unlinkSync(e);else{w.writeFileSync(e,p.code,"utf-8");let f=new Date(g);isNaN(f.getTime())||w.utimesSync(e,f,f)}return!0}else return this.log(`\u63A8\u9001\u5931\u8D25: ${t.formEngineKey}/${t.eventType} - ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u5F02\u5E38: ${t.formEngineKey}/${t.eventType} - ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async createEngine(e){let t=j.getInstance(),n=R.getInstance();this.log(`\u521B\u5EFA\u63A5\u53E3\u5F15\u64CE: ${e.apiEngineKey}...`);try{let r=bt({kind:"ApiEngine",key:e.apiEngineKey,currentCode:"",functionDescription:`\u63A5\u53E3\u5F15\u64CE ${e.apiName} \u7684\u5B8C\u6574\u4E1A\u52A1\u903B\u8F91\u3002`,changeSummary:`\u901A\u8FC7 VS Code \u521B\u5EFA\u63A5\u53E3\u5F15\u64CE ${e.apiEngineKey}`,initial:!0}),i=await t.post(K.CREATE_ENGINE,{OsClient:e.profile.osClient,ApiName:e.apiName,ApiEngineKey:e.apiEngineKey,ApiAddress:e.apiAddress||"",ApiRemark:e.apiRemark||"",Lock:e.lock?1:0,LockKey:e.lockKey||"",AllowAnonymous:e.allowAnonymous?1:0,V8Limit:e.v8Limit?1:0,IsEnable:e.isEnable!==!1?1:0,ApiRole:e.apiRole||"",Category:e.category||"\u672A\u5206\u7C7B",ApiV8CodeBase64:Buffer.from(r.code,"utf8").toString("base64"),Version:r.version,ChangeHistory:r.changeHistory},void 0,e.profile.apiBaseUrl,e.profile);if(i.Code===1){let o=n.getSyncRootDir(),a=n.buildServerDirName(e.profile.label,e.profile.apiBaseUrl),c=n.buildOsClientDirName(e.profile.osClient,e.profile.osClientType,e.profile.osClientNetwork),l=q(e.category||"\u672A\u5206\u7C7B"),p=q(e.apiName||e.apiEngineKey),u=v.join(o,a,c,Xe,l);ge(u);let d=v.join(u,q(`${p}(${In(e.apiEngineKey)}).js`));w.writeFileSync(d,r.code,"utf-8");let g=this.loadMeta(a);return g.engines[e.apiEngineKey]={id:"",apiName:e.apiName,category:l,apiAddress:e.apiAddress||"",updateTime:we(),filePath:v.relative(n.getWorkspaceRoot(),d)},this.saveMeta(g,a),this.log(`\u521B\u5EFA\u6210\u529F: ${e.apiEngineKey}`),M.info(`Microi: \u63A5\u53E3\u5F15\u64CE [${e.apiEngineKey}] \u521B\u5EFA\u6210\u529F`),await fe.showTextDocument(tr.file(d)),!0}else return this.log(`\u521B\u5EFA\u5931\u8D25: ${e.apiEngineKey} - ${i.Msg}`),M.error(`Microi: \u521B\u5EFA\u5931\u8D25 - ${i.Msg}`),!1}catch(r){let i=r instanceof Error?r.message:String(r);return this.log(`\u521B\u5EFA\u5F02\u5E38: ${e.apiEngineKey} - ${i}`),M.error(`Microi: \u521B\u5EFA\u5F02\u5E38 - ${i}`),!1}}async pullFields(e){if(!e){let t=R.getInstance().getProfiles();for(let n of t)try{await this.pullFieldsForProfile(n)}catch(r){this.log(`\u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${r instanceof Error?r.message:String(r)}`)}return}await this.pullFieldsForProfile(e)}async pullFieldsForTableFolder(e){let n=R.getInstance().getSyncRootDir(),r=v.relative(n,e).split(v.sep);if(r.length<4||r[2]!==Ve){M.warn("Microi: \u8BF7\u5728\u201C\u8868\u5355\u5F15\u64CE\u201D\u4E0B\u7684\u8868\u76EE\u5F55\u6267\u884C\u5B57\u6BB5 V8 \u4E8B\u4EF6\u62C9\u53D6");return}let i=a=>{let c=a.match(/[((]([^))]+)[))]\s*$/);return c?c[1]:a},o=this.findProfileByServerDir(r[0]);if(!o){M.error(`Microi: \u672A\u627E\u5230\u4E0E\u76EE\u5F55 "${r[0]}" \u5339\u914D\u7684\u670D\u52A1\u5668\u8FDE\u63A5`);return}await this.pullFieldsForTable(o,i(r[3]),e,r[0])}async pullFieldsForTable(e,t,n,r){let i=R.getInstance(),o=j.getInstance(),a=this.loadMeta(r);a.fields||(a.fields={}),this.log(`\u62C9\u53D6\u8868\u5B57\u6BB5V8\u4E8B\u4EF6: ${t}...`);let c=await o.get(K.GET_FIELD_LIST,{osClient:e.osClient,tableName:t},e.apiBaseUrl,e);if(c.Code!==1){M.error(`Microi: \u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 - ${c.Msg}`);return}let l=c.Data.List||[],p=["V8Code","KeyupV8Code","V8TmpEngineTable","V8TmpEngineForm"],u=0,d=0;for(let g of l){let m=q(g.Label?`${g.Label}\uFF08${g.Name}\uFF09`:g.Name),y=v.join(n,St,m);for(let f of p){let h=(g[f]||"").toString(),S=Sn[f]||f,C=q(`${S}\uFF08${f}\uFF09`)+".js",T=v.join(y,C),k=`${t}__${g.Name}__${f}`;if(!h.trim()){d++,w.existsSync(T)&&w.unlinkSync(T),delete a.fields[k];continue}ge(y),w.writeFileSync(T,h,"utf-8");let E=new Date(g.UpdateTime);isNaN(E.getTime())||w.utimesSync(T,E,E),a.fields[k]={fieldId:g.Id,tableId:g.TableId,tableName:t,fieldName:g.Name,fieldLabel:g.Label||"",v8Key:f,updateTime:g.UpdateTime,filePath:v.relative(i.getWorkspaceRoot(),T)},u++}}this.saveMeta(a,r),M.info(`Microi: \u5DF2\u62C9\u53D6 ${t} \u7684 ${u} \u4E2A\u5B57\u6BB5V8\u4E8B\u4EF6\u6587\u4EF6${d>0?`\uFF08\u8DF3\u8FC7 ${d} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)}async pullFieldsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6 [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6\u8868\u5217\u8868..."});let a=await n.get(K.GET_DB_SCHEMA,{osClient:i},r,e);if(a.Code!==1)throw new Error(`\u83B7\u53D6\u8868\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}`);let c=a.Data.Tables||[],p=await Ce.getInstance().getSysConfig(r,i),u=p?.SysShortTitle||"",d=p?.SysTitle||"",g=u||d||e.label||"",m=t.buildServerDirName(g,r),y=this.loadMeta(m);y.fields||(y.fields={});let h=t.getProfiles().find(F=>F.apiBaseUrl===e.apiBaseUrl&&F.osClient===e.osClient)||e;if(!h.osClientType||!h.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let S=t.buildOsClientDirName(i,h.osClientType,h.osClientNetwork),C=t.getSyncRootDir(),T=["V8Code","KeyupV8Code","V8TmpEngineTable","V8TmpEngineForm"],k=0,E=0,b=0,V=new Set,z=new Set;for(let F of c){b++,o.report({message:`[${b}/${c.length}] ${F.Name}`});let I=await n.get(K.GET_FIELD_LIST,{osClient:i,tableId:F.Id},r,e);if(I.Code!==1){z.add(F.Name.toLowerCase()),this.log(` \u8DF3\u8FC7\u8868 ${F.Name}: ${I.Msg}`);continue}let x=I.Data.List||[],A=q(F.Description?`${F.Description}\uFF08${F.Name}\uFF09`:F.Name);for(let D of x)for(let O of T){let J=(D[O]||"").toString();if(!J.trim()){E++;continue}let Y=q(D.Label?`${D.Label}\uFF08${D.Name}\uFF09`:D.Name),ue=Sn[O]||O,pe=q(`${ue}\uFF08${O}\uFF09`)+".js",te=v.join(C,m,S,Ve,A,St,Y);ge(te);let he=v.join(te,pe);w.writeFileSync(he,J,"utf-8");let le=new Date(D.UpdateTime);isNaN(le.getTime())||w.utimesSync(he,le,le);let N=`${F.Name}__${D.Name}__${O}`;V.add(N),y.fields[N]={fieldId:D.Id,tableId:D.TableId,tableName:F.Name,fieldName:D.Name,fieldLabel:D.Label||"",v8Key:O,updateTime:D.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),he)},k++}}for(let[F,I]of Object.entries(y.fields)){if(V.has(F)||z.has(I.tableName.toLowerCase()))continue;let x=this.getWorkspaceFilePath(I.filePath);x&&this.backupAndDeleteSyncFile(x,m,"remote-deleted-field-event"),delete y.fields[F]}this.saveMeta(y,m),this.log(`\u5B57\u6BB5V8\u4E8B\u4EF6\u62C9\u53D6\u5B8C\u6210: ${k} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${E} \u9879`),M.info(`Microi: \u6210\u529F\u62C9\u53D6 ${k} \u4E2A\u5B57\u6BB5V8\u4E8B\u4EF6${E>0?`\uFF08\u8DF3\u8FC7 ${E} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)})}async pushFieldFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u5B57\u6BB5V8\u4E8B\u4EF6: ${t.tableName}/${t.fieldName}/${t.v8Key}...`);try{let o=await r.post(K.UPDATE_FIELD,{OsClient:t.osClient,TableName:t.tableName,Name:t.fieldName,[t.v8Key]:i},void 0,n?.apiBaseUrl,n);if(o.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.tableName}/${t.fieldName}/${t.v8Key}`);let a=this.loadMeta(t.serverDir),c=`${t.tableName}__${t.fieldName}__${t.v8Key}`;a.fields||(a.fields={});let l=o.Data?.UpdateTime||we();return i.trim()?a.fields[c]={fieldId:a.fields[c]?.fieldId||"",tableId:a.fields[c]?.tableId||"",tableName:t.tableName,fieldName:t.fieldName,fieldLabel:a.fields[c]?.fieldLabel||"",v8Key:t.v8Key,updateTime:l,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}:delete a.fields[c],this.saveMeta(a,t.serverDir),i.trim()?this.touchSyncedFile(e,l):w.existsSync(e)&&w.unlinkSync(e),!0}return this.log(`\u63A8\u9001\u5931\u8D25: ${o.Msg}`),M.error(`Microi: \u63A8\u9001\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 - ${o.Msg}`),!1}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${a}`),!1}}async pullMenuButtons(e){if(!e){let t=R.getInstance().getProfiles();for(let n of t)try{await this.pullMenuButtonsForProfile(n)}catch(r){this.log(`\u62C9\u53D6\u83DC\u5355\u6309\u94AE\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${r instanceof Error?r.message:String(r)}`)}return}await this.pullMenuButtonsForProfile(e)}async pullMenuButtonsForModuleFolder(e){let n=R.getInstance().getSyncRootDir(),r=v.relative(n,e).split(v.sep);if(r.length<4||r[2]!==je){M.warn("Microi: \u8BF7\u5728\u201C\u6A21\u5757\u5F15\u64CE\u201D\u4E0B\u7684\u6A21\u5757\u76EE\u5F55\u6267\u884C\u62C9\u53D6");return}let i=this.findProfileByServerDir(r[0]);if(!i){M.error(`Microi: \u672A\u627E\u5230\u4E0E\u76EE\u5F55 "${r[0]}" \u5339\u914D\u7684\u670D\u52A1\u5668\u8FDE\u63A5`);return}let o=this.extractTrailingKey(v.basename(e));await this.pullMenuButtonsForProfile(i,o,r[0],r[1],e)}async pullMenuButtonsForProfile(e,t,n,r,i){let o=R.getInstance(),a=j.getInstance(),c=e.apiBaseUrl,l=e.osClient;this.log(`\u5F00\u59CB\u62C9\u53D6\u6A21\u5757 Join/Where \u4E0E\u6309\u94AE V8 \u4EE3\u7801 [${e.label||c}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u6A21\u5757\u4EE3\u7801 [${e.label||c}]`,cancellable:!1},async p=>{let u=await a.get(K.LIST_MODULES,{osClient:l},c,e);if(u.Code!==1)throw new Error(`\u83B7\u53D6\u6A21\u5757\u5217\u8868\u5931\u8D25: ${u.Msg}`);let d=u.Data.List||[],m=await Ce.getInstance().getSysConfig(c,l),y=m?.SysShortTitle||"",f=m?.SysTitle||"",h=y||f||e.label||"",S=n||o.buildServerDirName(h,c),C=this.loadMeta(S);C.menus||(C.menus={}),C.menuButtons||(C.menuButtons={}),C.menuScripts||(C.menuScripts={});let k=o.getProfiles().find(N=>N.apiBaseUrl===e.apiBaseUrl&&N.osClient===e.osClient)||e;if(!k.osClientType||!k.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let E=r||o.buildOsClientDirName(l,k.osClientType,k.osClientNetwork),b=o.getSyncRootDir(),V=v.join(b,S,E,je),z=Object.keys(et),F=Object.keys(Ct),I=0,x=0,A=0,D=0,O=0,J=new Map(d.map(N=>[N.Id,N])),Y=new Map,ue=N=>N||"";for(let N of d){let me=ue(N.ParentId);Y.has(me)||Y.set(me,[]),Y.get(me).push(N)}let pe=N=>N.sort((me,se)=>{let ye=typeof me.Sort=="number"?me.Sort:0,ft=typeof se.Sort=="number"?se.Sort:0;return ye!==ft?ye-ft:String(me.Name||me.Label||"").localeCompare(String(se.Name||se.Label||""))}),te=t?J.get(t)?[J.get(t)]:[]:pe(d.filter(N=>!N.ParentId||!J.has(N.ParentId)));if(t&&te.length===0)throw new Error(`\u627E\u4E0D\u5230\u6A21\u5757 Id=${t}`);let he=t?i||v.join(V,q(`${te[0].Label||te[0].Name||te[0].Id}\uFF08${te[0].Id}\uFF09`)):V;if(this.backupExistingTree(he,S,t?"module-subtree":"module-engine"),!t)C.menus={},C.menuButtons={},C.menuScripts={};else{let N=new Set,me=se=>{if(!N.has(se)){N.add(se);for(let ye of Y.get(se)||[])me(ye.Id)}};me(t);for(let se of N)delete C.menus[se];for(let[se,ye]of Object.entries(C.menuButtons))N.has(ye.moduleId)&&delete C.menuButtons[se];for(let[se,ye]of Object.entries(C.menuScripts))N.has(ye.moduleId)&&delete C.menuScripts[se]}let le=async(N,me)=>{D++,p.report({message:`[${D}/${d.length}] ${N.Name||N.Label}`});let se=N.Label||N.Name||N.Id,ye=v.join(me,q(`${se}\uFF08${N.Id}\uFF09`));ge(ye);let ft=pe(Y.get(N.Id)||[]);if(ft.length>0){for(let de of ft)await le(de,ye);return}let gn=await a.get(K.GET_MODULE,{osClient:l,moduleId:N.Id},c,e);if(gn.Code!==1){this.log(` \u8DF3\u8FC7\u6A21\u5757 ${N.Name}: ${gn.Msg}`);return}let pn=gn.Data,Le=String(pn.UpdateTime||we()),Jn={};for(let de of F){let Vt=String(pn[de]||""),mn=Ct[de]||de,Be=v.join(ye,q(`${mn}\uFF08${de}\uFF09`)+".js");w.writeFileSync(Be,Vt,"utf-8"),this.touchSyncedFile(Be,Le),C.menuScripts[this.getMenuScriptMetaKey(N.Id,de)]={moduleId:N.Id,moduleName:se,scriptField:de,codeHash:this.sourceHash(Vt),updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),Be)},A++}for(let de of z){let Vt=et[de]||de,mn=q(`${Vt}\uFF08${de}\uFF09`),Be=v.join(ye,mn);ge(Be),x++;let xt=pn[de],Ge=[];if(xt)try{Ge=typeof xt=="string"?JSON.parse(xt):xt,Array.isArray(Ge)||(Ge=[])}catch{this.log(` \u6309\u94AE JSON \u89E3\u6790\u5931\u8D25 ${N.Name}.${de}`),Ge=[]}let ys=[...Ge].sort((ze,ke)=>String(ze.Id||"").localeCompare(String(ke.Id||"")));Jn[de]=require("crypto").createHash("sha1").update(JSON.stringify(ys)).digest("hex");for(let ze of Ge){let ke=String(ze.Id||""),Ot=String(ze.Name||ke||"Unknown");if(!ke)continue;let qn=String(ze.V8Code||""),fn=v.join(Be,q(`${Ot}\uFF08${ke}\uFF09`)+".js");C.menuButtons[this.getMenuButtonMetaKey(N.Id,de,ke,"V8Code")]={moduleId:N.Id,moduleName:se,btnField:de,btnId:ke,btnName:Ot,v8SubField:"V8Code",updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),fn)},qn.trim()?(w.writeFileSync(fn,qn,"utf-8"),this.touchSyncedFile(fn,Le),I++):O++;let Qn=String(ze.V8CodeShow||"");if(Qn.trim()){let hn=v.join(Be,q(`${Ot}_\u663E\u9690\u5224\u65AD\uFF08${ke}\uFF09`)+".js");w.writeFileSync(hn,Qn,"utf-8"),this.touchSyncedFile(hn,Le),C.menuButtons[this.getMenuButtonMetaKey(N.Id,de,ke,"V8CodeShow")]={moduleId:N.Id,moduleName:se,btnField:de,btnId:ke,btnName:Ot,v8SubField:"V8CodeShow",updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),hn)},I++}else O++}}C.menus[N.Id]={moduleId:N.Id,moduleName:se,updateTime:Le,buttonHashes:Jn}};ge(V);for(let N of te)await le(N,V);this.saveMeta(C,S),this.log(`\u6A21\u5757\u4EE3\u7801\u62C9\u53D6\u5B8C\u6210: ${I} \u4E2A\u6309\u94AEV8\u6587\u4EF6\uFF0C${A} \u4E2A Join/Where \u6587\u4EF6\uFF0C${x} \u4E2A\u6309\u94AE\u76EE\u5F55\uFF0C\u8DF3\u8FC7\u7A7A\u6309\u94AE\u4EE3\u7801 ${O} \u9879`),M.info(`Microi: \u6210\u529F\u62C9\u53D6 ${I} \u4E2A\u6309\u94AEV8\u6587\u4EF6\u548C ${A} \u4E2A Join/Where \u6587\u4EF6${O>0?`\uFF08\u8DF3\u8FC7 ${O} \u4E2A\u7A7A\u6309\u94AE\u4EE3\u7801\uFF09`:""}\uFF0C\u5DF2\u751F\u6210 ${x} \u4E2A\u6309\u94AE\u76EE\u5F55`)})}backupExistingTree(e,t,n){if(!w.existsSync(e))return;let i=R.getInstance().getSyncRootDir();this.ensureSyncGitExcludes(i);let o=v.join(i,".backups",n,this.shortBackupKey(t));ge(o);let a=v.join(o,`${Date.now()}-${this.shortBackupKey(v.basename(e))}`);w.renameSync(e,a)}backupAndDeleteSyncFile(e,t,n){if(!w.existsSync(e))return;let r=R.getInstance(),i=r.getSyncRootDir();this.ensureSyncGitExcludes(i);let o=r.getWorkspaceRoot()||i,c=v.relative(o,e).split(v.sep).filter(u=>u&&u!=="..").map(q),l=v.join(i,".backups",n,this.shortBackupKey(t),String(Date.now())),p=v.join(l,...c.length?c:[q(v.basename(e))]);ge(v.dirname(p)),w.copyFileSync(e,p),w.unlinkSync(e)}async pushMenuScriptFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u6A21\u5757\u811A\u672C: ${t.moduleId}.${t.scriptField}...`);try{let o=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n);if(o.Code!==1||!o.Data)return M.error(`Microi: \u63A8\u9001\u5931\u8D25 - \u62C9\u53D6\u6A21\u5757\u5931\u8D25 ${o.Msg}`),!1;let a=o.Data,c=String(a[t.scriptField]||""),l=R.getInstance(),p=l.getSyncRootDir();this.ensureSyncGitExcludes(p);let u=v.join(p,".backups","menu-script",this.shortBackupKey(t.serverDir),t.moduleId);ge(u),w.writeFileSync(v.join(u,`${t.scriptField}-${Date.now()}.js`),c,"utf-8");let d={OsClient:t.osClient,ModuleId:t.moduleId,[t.scriptField]:i},g=await r.post(K.UPDATE_MODULE,d,void 0,n?.apiBaseUrl,n);if(g.Code!==1)return M.error(`Microi: \u63A8\u9001\u6A21\u5757 ${t.scriptField} \u5931\u8D25 - ${g.Msg}`),!1;let m=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n),y=m.Data;if(m.Code!==1||!y||this.normalizeCode(String(y[t.scriptField]||""))!==this.normalizeCode(i))return M.error(`Microi: ${t.scriptField} \u63A5\u53E3\u8FD4\u56DE\u6210\u529F\uFF0C\u4F46\u8FDC\u7AEF\u56DE\u8BFB\u4E0D\u4E00\u81F4\uFF1B\u5DF2\u4FDD\u7559\u672C\u5730\u4FEE\u6539\u548C\u8FDC\u7AEF\u5907\u4EFD`),!1;let f=String(y.UpdateTime||g.Data?.UpdateTime||we()),h=this.loadMeta(t.serverDir);return h.menuScripts||(h.menuScripts={}),h.menuScripts[this.getMenuScriptMetaKey(t.moduleId,t.scriptField)]={moduleId:t.moduleId,moduleName:String(y.Label||y.Name||a.Label||a.Name||t.moduleId),scriptField:t.scriptField,codeHash:this.sourceHash(i),updateTime:f,filePath:v.relative(l.getWorkspaceRoot(),e)},h.menus||(h.menus={}),h.menus[t.moduleId]={moduleId:t.moduleId,moduleName:String(y.Label||y.Name||a.Label||a.Name||t.moduleId),updateTime:f,buttonHashes:h.menus[t.moduleId]?.buttonHashes||{}},this.saveMeta(h,t.serverDir),this.touchSyncedFile(e,f),this.log(`\u63A8\u9001\u5E76\u56DE\u8BFB\u6210\u529F: ${t.moduleId}.${t.scriptField}`),!0}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u6A21\u5757\u811A\u672C\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u6A21\u5757\u811A\u672C\u5F02\u5E38 - ${a}`),!1}}async pushMenuButtonFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u6309\u94AEV8\u4EE3\u7801: ${t.moduleId}.${t.btnField}.${t.btnId}.${t.v8SubField}...`);try{let o=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n);if(o.Code!==1)return M.error(`Microi: \u63A8\u9001\u5931\u8D25 - \u62C9\u53D6\u6A21\u5757\u5931\u8D25 ${o.Msg}`),!1;let a=o.Data,c=[],l=a[t.btnField];if(l)try{c=typeof l=="string"?JSON.parse(l):l,Array.isArray(c)||(c=[])}catch{return M.error("Microi: \u63A8\u9001\u5931\u8D25 - \u6309\u94AE JSON \u89E3\u6790\u5931\u8D25"),!1}let u=R.getInstance().getSyncRootDir();this.ensureSyncGitExcludes(u);let d=v.join(u,".backups","menu-button-json",this.shortBackupKey(t.serverDir),t.moduleId);ge(d);let g=v.join(d,`${t.btnField}-${Date.now()}.json`);w.writeFileSync(g,JSON.stringify(c,null,2),"utf-8");let m=c.find(h=>String(h.Id||"")===t.btnId);if(!m){let h=c.map(S=>Number(S.Sort||0)).filter(S=>!isNaN(S));m={Id:t.btnId,Name:t.btnName||t.btnId,Sort:h.length>0?Math.max(...h)+1:c.length+1,IsVisible:!0,ShowRow:t.btnField==="MoreBtns"},c.push(m)}m[t.v8SubField]=i;let y={OsClient:t.osClient,ModuleId:t.moduleId};y[t.btnField]=JSON.stringify(c);let f=await r.post(K.UPDATE_MODULE,y,void 0,n?.apiBaseUrl,n);if(f.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.moduleId}.${t.btnField}.${t.btnId}.${t.v8SubField}`);let h=f.Data?.UpdateTime||we(),S=this.loadMeta(t.serverDir);S.menuButtons||(S.menuButtons={});let C=this.getMenuButtonMetaKey(t.moduleId,t.btnField,t.btnId,t.v8SubField);return i.trim()?S.menuButtons[C]={moduleId:t.moduleId,moduleName:String(a.Name||a.Label||t.moduleId),btnField:t.btnField,btnId:t.btnId,btnName:String(m.Name||t.btnName||t.btnId),v8SubField:t.v8SubField,updateTime:h,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}:delete S.menuButtons[C],S.menus||(S.menus={}),S.menus[t.moduleId]={moduleId:t.moduleId,moduleName:String(a.Name||a.Label||t.moduleId),updateTime:h,buttonHashes:S.menus[t.moduleId]?.buttonHashes||{}},this.saveMeta(S,t.serverDir),i.trim()?this.touchSyncedFile(e,h):w.existsSync(e)&&w.unlinkSync(e),!0}return M.error(`Microi: \u63A8\u9001\u6309\u94AE\u5931\u8D25 - ${f.Msg}`),!1}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${a}`),!1}}async pushWorkflowNodeFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8: ${t.flowDesignId}/${t.nodeId}/${t.eventType}...`);try{let a="",c="";try{let g=await r.post(K.GET_WORKFLOW_V8_EVENT_CODE,{OsClient:t.osClient,FlowDesignId:t.flowDesignId,NodeId:t.nodeId,EventType:t.eventType},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.V8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"Workflow",key:`${t.flowDesignId}/${t.nodeId}`,eventType:t.eventType,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001\u6D41\u7A0B\u8282\u70B9 V8 ${t.flowDesignId}/${t.nodeId}/${t.eventType}`}),u={OsClient:t.osClient,FlowDesignId:t.flowDesignId,NodeId:t.nodeId,EventType:t.eventType};l?u.V8Code="":(u.V8CodeBase64=Buffer.from(p.code,"utf8").toString("base64"),u.Version=p.version,u.ChangeHistory=p.changeHistory);let d=await r.post(K.UPDATE_WORKFLOW_V8_EVENT_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir);m.workflowNodeEvents||(m.workflowNodeEvents={});let y=`${t.flowDesignId}__${t.nodeId}__${t.eventType}`;return l?delete m.workflowNodeEvents[y]:m.workflowNodeEvents[y]={flowDesignId:t.flowDesignId,flowName:m.workflowNodeEvents[y]?.flowName||t.flowDesignId,nodeId:t.nodeId,nodeName:m.workflowNodeEvents[y]?.nodeName||t.nodeId,eventType:t.eventType,updateTime:g,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)},this.saveMeta(m,t.serverDir),l?w.existsSync(e)&&w.unlinkSync(e):(w.writeFileSync(e,p.code,"utf-8"),this.touchSyncedFile(e,g)),this.log(`\u63A8\u9001\u6210\u529F: ${t.flowDesignId}/${t.nodeId}/${t.eventType}`),!0}return this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5931\u8D25: ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5F02\u5E38: ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async pullDbSchema(e){let t=R.getInstance(),n=j.getInstance();if(!e){let r=t.getProfiles();if(r.length===0){M.warn("Microi: \u6CA1\u6709\u5DF2\u8FDE\u63A5\u7684\u670D\u52A1\u5668");return}for(let i of r)try{await this.pullDbSchemaForProfile(i)}catch(o){let a=o instanceof Error?o.message:String(o);this.log(`\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5931\u8D25 [${i.label||i.apiBaseUrl}]: ${a}`)}return}await this.pullDbSchemaForProfile(e)}async pullDbSchemaForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784 [${e.label||r}]...`);let o=await n.get(K.GET_DB_SCHEMA,{osClient:i},r,e);if(o.Code!==1){let b=o.Code===1001||o.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5931\u8D25: ${o.Msg||"Code="+o.Code}${b}`)}let a=t.getSyncRootDir(),l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u});let g=t.buildServerDirName(d,r),y=t.getProfiles().find(b=>b.apiBaseUrl===e.apiBaseUrl&&b.osClient===e.osClient)||e,f=t.buildOsClientDirName(i,y.osClientType,y.osClientNetwork),h=v.join(a,g,f);ge(h);let S=v.join(h,tt);w.writeFileSync(S,JSON.stringify(o.Data,null,2),"utf-8");let C=v.join(h,He),T=this.formatDbSchemaMarkdown(o.Data,g,f);T&&w.writeFileSync(C,T,"utf-8");let k=o.Data.Tables?.length||0,E=d||e.label||r;this.log(`[${E}] \u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5B8C\u6210: ${k} \u5F20\u8868`),M.info(`Microi: [${E}] \u6210\u529F\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\uFF08${k} \u5F20\u8868\uFF09`)}formatDbSchemaMarkdown(e,t,n){let r=(e.Tables||[]).filter(c=>c.Name);if(!r.length)return"";let i=r.reduce((c,l)=>{let p=l._Fields||l.Fields||[];return c+p.length},0),o=e.Menus?.length||0,a=[];a.push(`# \u6570\u636E\u5E93\u7ED3\u6784 \u2014 ${t}/${n}
|
|
41
|
+
`).trimEnd()}isLocalModified(e,t){try{if(!w.existsSync(e))return!1;let n=w.statSync(e),r=new Date(t);return isNaN(r.getTime())?!1:n.mtime.getTime()>r.getTime()+1e3}catch{return!1}}getLocalModifiedTime(e,t){try{if(!w.existsSync(e))return null;let n=w.statSync(e),r=new Date(t);return isNaN(r.getTime())?null:n.mtime.getTime()>r.getTime()+1e3?we(n.mtime):null}catch{return null}}touchSyncedFile(e,t){let n=new Date(t),r=isNaN(n.getTime())?new Date:n;try{w.utimesSync(e,r,r)}catch{}}ensureSyncGitExcludes(e){try{let t=e||R.getInstance().getSyncRootDir();rt(t),xe(t,[".backups/","**/.backups/",".microi-mcp-tokens.json","**/.microi-mcp-tokens.json"])}catch{}}shortBackupKey(e){return require("crypto").createHash("sha1").update(e||"").digest("hex").slice(0,10)}getMenuButtonMetaKey(e,t,n,r){return`${e}__${t}__${n}__${r}`}getMenuScriptMetaKey(e,t){return`${e}__${t}`}sourceHash(e){return require("crypto").createHash("sha256").update(this.normalizeCode(e||"")).digest("hex")}extractTrailingKey(e){let t=e.match(/[((]([^))]+)[))]\s*$/);return t?t[1]:e}getServerDirs(){try{let e=R.getInstance().getSyncRootDir();return w.existsSync(e)?w.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).filter(t=>!t.name.startsWith(".")).map(t=>t.name):[]}catch{return[]}}getLocalChangeSummary(){let e={engines:0,events:0,fields:0,menuButtons:0,menuScripts:0,workflowNodeEvents:0,total:0};for(let t of this.getLocalChangeItems())t.kind==="engine"?e.engines+=1:t.kind==="event"?e.events+=1:t.kind==="field"?e.fields+=1:t.kind==="menuButton"?e.menuButtons+=1:t.kind==="menuScript"?e.menuScripts+=1:t.kind==="workflow"&&(e.workflowNodeEvents+=1);return e.total=e.engines+e.events+e.fields+e.menuButtons+e.menuScripts+e.workflowNodeEvents,e}getLocalChangeItems(){let e=[],t=(n,r,i,o,a)=>{let c=this.getWorkspaceFilePath(a.filePath);if(!c)return;let l=this.getLocalModifiedTime(c,a.updateTime);l&&e.push({kind:r,key:i,name:o,serverDir:n,filePath:c,updateTime:a.updateTime,modifiedTime:l})};for(let n of this.getServerDirs()){let r=this.loadMeta(n);for(let[i,o]of Object.entries(r.engines))t(n,"engine",i,o.apiName||i,o);for(let[i,o]of Object.entries(r.events))t(n,"event",i,`${o.description||o.formEngineKey}/${o.eventType}`,o);for(let[i,o]of Object.entries(r.fields||{}))t(n,"field",i,`${o.tableName}.${o.fieldName}/${o.v8Key}`,o);for(let[i,o]of Object.entries(r.menuButtons||{}))t(n,"menuButton",i,`${o.moduleName}/${o.btnName}/${o.v8SubField}`,o);for(let[i,o]of Object.entries(r.menuScripts||{}))t(n,"menuScript",i,`${o.moduleName}/${o.scriptField}`,o);for(let[i,o]of Object.entries(r.workflowNodeEvents||{}))t(n,"workflow",i,`${o.flowName}/${o.nodeName}/${o.eventType}`,o)}return e}async checkRemoteDifferences(e,t="all",n){let r=e?[e]:R.getInstance().getProfiles(),i=[];for(let o of r){let a=R.getInstance().buildServerDirName(o.label,o.apiBaseUrl),c=this.loadMeta(a),l=n?this.getTargetSyncKind(c,n):null;if(n&&!l)throw new Error(`\u540C\u6B65\u76EE\u6807\u4E0D\u5728\u672C\u5730\u57FA\u7EBF\u4E2D: ${n}`);(t==="all"||t==="api")&&(!n||l==="engine")&&await this.collectEngineDifferences(o,a,c,i,n),(t==="all"||t==="form")&&(!n||l==="event")&&await this.collectEventDifferences(o,a,c,i,n),(t==="all"||t==="form")&&(!n||l==="field")&&await this.collectFieldDifferences(o,a,c,i,n),(t==="all"||t==="module")&&(!n||l==="menuButton")&&await this.collectMenuButtonDifferences(o,a,c,i,n),(t==="all"||t==="module")&&(!n||l==="menuScript")&&await this.collectMenuScriptDifferences(o,a,c,i,n),(t==="all"||t==="workflow")&&(!n||l==="workflow")&&await this.collectWorkflowDifferences(o,a,c,i,n)}return i}matchesTargetFile(e,t){if(!t)return!0;let n=this.getWorkspaceFilePath(e);return!!n&&v.resolve(n).toLowerCase()===v.resolve(t).toLowerCase()}getTargetSyncKind(e,t){let n=[["engine",e.engines],["event",e.events],["field",e.fields||{}],["menuButton",e.menuButtons||{}],["menuScript",e.menuScripts||{}],["workflow",e.workflowNodeEvents||{}]];for(let[r,i]of n)if(Object.values(i).some(o=>this.matchesTargetFile(o.filePath,t)))return r;return null}classifyDifference(e,t,n,r){return n===r?null:e&&t?"conflict":e?"localModified":"remoteModified"}classifyRemoteDeletion(e,t){return this.isLocalModified(e,t)?"conflict":"remoteDeleted"}createRemoteDeletedItem(e,t,n,r,i,o){return!i||!w.existsSync(i)?null:{kind:e,status:this.classifyRemoteDeletion(i,o),name:t,key:n,serverDir:r,filePath:i,localCode:this.normalizeCode(w.readFileSync(i,"utf-8")),remoteCode:"",localUpdateTime:o,remoteUpdateTime:""}}isRemoteNewer(e,t){let n=new Date(e||"").getTime(),r=new Date(t||"").getTime();return isNaN(n)||isNaN(r)?!1:n>r+1e3}getRemoteOnlyPlaceholderPath(e,t,n,r){let i=R.getInstance(),o=n==="api"?Xe:n==="form"?Ve:n==="module"?je:Ze;return v.join(i.getSyncRootDir(),t,i.buildOsClientDirName(e.osClient,e.osClientType,e.osClientNetwork),o,"\u670D\u52A1\u5668\u65B0\u589E\u5F85\u62C9\u53D6",`${q(r)}.js`)}async collectEngineDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_ENGINE_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u63A5\u53E3\u5F15\u64CE\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map(a.Data.List.map(u=>[u.ApiEngineKey,u])),l=!1;for(let[u,d]of Object.entries(n.engines)){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g){let T=this.createRemoteDeletedItem("engine",d.apiName||u,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.ApiV8Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);C&&r.push({kind:"engine",status:C,name:g.ApiName||d.apiName||u,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.engines).map(u=>u.toLowerCase()));for(let u of a.Data.List)!String(u.ApiV8Code||"").trim()||p.has(u.ApiEngineKey.toLowerCase())||r.push({kind:"engine",status:"remoteModified",name:u.ApiName||u.ApiEngineKey,key:u.ApiEngineKey,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"api",u.ApiEngineKey),localCode:"",remoteCode:this.normalizeCode(u.ApiV8Code||""),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}async collectEventDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_EVENT_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u8868\u5355\u4E8B\u4EF6\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map;for(let u of a.Data.List){let d=`${u.FormEngineKey}__${u.EventType}`;c.set(d,u),c.set(d.toLowerCase(),u)}let l=!1;for(let[u,d]of Object.entries(n.events)){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u)||c.get(u.toLowerCase()),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g){let T=this.createRemoteDeletedItem("event",`${d.description||d.formEngineKey}/${d.eventType}`,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.V8Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);C&&r.push({kind:"event",status:C,name:`${g.Description||d.formEngineKey}/${d.eventType}`,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.events).map(u=>u.toLowerCase()));for(let u of a.Data.List){let d=`${u.FormEngineKey}__${u.EventType}`;!String(u.V8Code||"").trim()||p.has(d.toLowerCase())||r.push({kind:"event",status:"remoteModified",name:`${u.Description||u.FormEngineKey}/${u.EventType}`,key:d,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"form",d),localCode:"",remoteCode:this.normalizeCode(u.V8Code||""),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}}async collectFieldDifferences(e,t,n,r,i){let o=j.getInstance(),a=new Map;for(let l of Object.entries(n.fields||{})){if(!this.matchesTargetFile(l[1].filePath,i))continue;let p=a.get(l[1].tableId||l[1].tableName)||[];p.push(l),a.set(l[1].tableId||l[1].tableName,p)}let c=!1;await this.runInBatches([...a.values()],i?1:2,async l=>{let p=l[0][1],u=await o.get(K.GET_FIELD_LIST,{osClient:e.osClient,tableId:p.tableId,tableName:p.tableName},e.apiBaseUrl,e);if(u.Code!==1||!Array.isArray(u.Data?.List))throw new Error(`\u83B7\u53D6\u5B57\u6BB5\u540C\u6B65\u72B6\u6001\u5931\u8D25[${p.tableName}]: ${u.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let d=new Map(u.Data.List.map(g=>[String(g.Name||"").toLowerCase(),g]));for(let[g,m]of l){let y=d.get(m.fieldName.toLowerCase()),f=this.getWorkspaceFilePath(m.filePath);if(!f||!w.existsSync(f))continue;if(!y||!String(y[m.v8Key]||"").trim()){let b=this.createRemoteDeletedItem("field",`${m.tableName}.${m.fieldName}/${m.v8Key}`,g,t,f,m.updateTime);b&&r.push(b);continue}let h=this.normalizeCode(w.readFileSync(f,"utf-8")),S=this.normalizeCode(String(y[m.v8Key]||"")),C=String(y.UpdateTime||""),T=this.isLocalModified(f,m.updateTime),k=this.isRemoteNewer(C,m.updateTime);if(h===S){(T||k)&&C&&(m.updateTime=C,this.touchSyncedFile(f,C),c=!0);continue}let E=this.classifyDifference(T,k,h,S);E&&r.push({kind:"field",status:E,name:`${m.tableName}.${m.fieldName}/${m.v8Key}`,key:g,serverDir:t,filePath:f,localCode:h,remoteCode:S,localUpdateTime:m.updateTime,remoteUpdateTime:C})}}),c&&this.saveMeta(n,t)}async collectMenuButtonDifferences(e,t,n,r,i){let o=j.getInstance(),a=new Map;if(!i)for(let d of Object.keys(n.menus||{}))a.set(d,[]);for(let d of Object.entries(n.menuButtons||{})){if(!this.matchesTargetFile(d[1].filePath,i))continue;let g=a.get(d[1].moduleId)||[];g.push(d),a.set(d[1].moduleId,g)}let c=[];if(!i){let d=await o.get(K.LIST_MODULES,{osClient:e.osClient},e.apiBaseUrl,e);if(d.Code!==1||!Array.isArray(d.Data?.List))throw new Error(`\u83B7\u53D6\u6A21\u5757\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${d.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);c=d.Data.List}let l=new Set(c.map(d=>String(d.ParentId||"")).filter(Boolean)),p=new Map(c.map(d=>[d.Id,d]));for(let d of c){if(l.has(d.Id)||n.menus?.[d.Id])continue;let g=d.Label||d.Name||d.Id;r.push({kind:"menuButton",status:"remoteModified",name:`${g}/\u670D\u52A1\u5668\u65B0\u589E\u6A21\u5757`,key:d.Id,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"module",d.Id),localCode:"",remoteCode:JSON.stringify(d,null,2),localUpdateTime:"",remoteUpdateTime:String(d.UpdateTime||"")})}let u=!1;await this.runInBatches([...a.entries()],i?1:2,async([d,g])=>{let m=()=>{for(let[k,E]of g){let b=this.getWorkspaceFilePath(E.filePath);if(!b)continue;let V=this.createRemoteDeletedItem("menuButton",`${E.moduleName}/${E.btnName}/${E.v8SubField}`,k,t,b,E.updateTime);V&&r.push(V)}};if(!i&&!p.has(d)){m();return}let y=await o.get(K.GET_MODULE,{osClient:e.osClient,moduleId:d},e.apiBaseUrl,e);if(y.Code!==1||!y.Data){if(/不存在|not\s*found/i.test(String(y.Msg||""))){m();return}throw new Error(`\u83B7\u53D6\u6A21\u5757\u6309\u94AE\u540C\u6B65\u72B6\u6001\u5931\u8D25[${d}]: ${y.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`)}let f=y.Data,h=String(f.UpdateTime||""),S=new Map;for(let k of Object.keys(et)){let E=[];try{let b=f[k];E=typeof b=="string"?JSON.parse(b):Array.isArray(b)?b:[],Array.isArray(E)||(E=[])}catch{E=[]}S.set(k,new Map(E.map(b=>[String(b.Id||""),b])))}for(let[k,E]of g){let b=S.get(E.btnField)?.get(E.btnId),V=this.getWorkspaceFilePath(E.filePath);if(!V||!w.existsSync(V))continue;if(!b||!String(b[E.v8SubField]||"").trim()){let D=this.createRemoteDeletedItem("menuButton",`${E.moduleName}/${E.btnName}/${E.v8SubField}`,k,t,V,E.updateTime);D&&r.push(D);continue}let z=this.normalizeCode(w.readFileSync(V,"utf-8")),F=this.normalizeCode(String(b[E.v8SubField]||"")),I=this.isLocalModified(V,E.updateTime),x=this.isRemoteNewer(h,E.updateTime);if(z===F){(I||x)&&h&&(E.updateTime=h,this.touchSyncedFile(V,h),u=!0);continue}let A=this.classifyDifference(I,x,z,F);A&&r.push({kind:"menuButton",status:A,name:`${E.moduleName}/${E.btnName}/${E.v8SubField}`,key:k,serverDir:t,filePath:V,localCode:z,remoteCode:F,localUpdateTime:E.updateTime,remoteUpdateTime:h})}if(i)return;let C=new Set(g.map(([k])=>k)),T=n.menus?.[d]?.moduleName||p.get(d)?.Label||p.get(d)?.Name||d;for(let[k,E]of S)for(let[b,V]of E){if(!b)continue;let z=String(V.Name||b);for(let F of["V8Code","V8CodeShow"]){let I=String(V[F]||""),x=this.getMenuButtonMetaKey(d,k,b,F);!I.trim()||C.has(x)||r.push({kind:"menuButton",status:"remoteModified",name:`${T}/${z}/${F}`,key:x,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"module",x),localCode:"",remoteCode:this.normalizeCode(I),localUpdateTime:"",remoteUpdateTime:h})}}}),u&&this.saveMeta(n,t)}async collectMenuScriptDifferences(e,t,n,r,i){let o=j.getInstance(),a=Object.entries(n.menuScripts||{}).filter(([,l])=>this.matchesTargetFile(l.filePath,i)),c=!1;await this.runInBatches(a,i?1:2,async([l,p])=>{let u=this.getWorkspaceFilePath(p.filePath);if(!u||!w.existsSync(u))return;let d=await o.get(K.GET_MODULE,{osClient:e.osClient,moduleId:p.moduleId},e.apiBaseUrl,e);if(d.Code!==1||!d.Data){if(/不存在|not\s*found/i.test(String(d.Msg||""))){let T=this.createRemoteDeletedItem("menuScript",`${p.moduleName}/${p.scriptField}`,l,t,u,p.updateTime);T&&r.push(T);return}throw new Error(`\u83B7\u53D6\u6A21\u5757 Join/Where \u540C\u6B65\u72B6\u6001\u5931\u8D25[${p.moduleId}]: ${d.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`)}let g=d.Data,m=this.normalizeCode(String(g[p.scriptField]||"")),y=this.normalizeCode(w.readFileSync(u,"utf-8")),f=String(g.UpdateTime||""),h=this.isLocalModified(u,p.updateTime),S=this.sourceHash(m)!==p.codeHash;if(y===m){(h||S||f&&f!==p.updateTime)&&(p.codeHash=this.sourceHash(m),p.updateTime=f||p.updateTime,this.touchSyncedFile(u,p.updateTime),c=!0);return}let C=this.classifyDifference(h,S,y,m);C&&r.push({kind:"menuScript",status:C,name:`${p.moduleName}/${p.scriptField}`,key:l,serverDir:t,filePath:u,localCode:y,remoteCode:m,localUpdateTime:p.updateTime,remoteUpdateTime:f})}),c&&this.saveMeta(n,t)}async runInBatches(e,t,n){for(let r=0;r<e.length;r+=t)await Promise.all(e.slice(r,r+t).map(i=>n(i))),r+t<e.length&&await new Promise(i=>setTimeout(i,120))}async collectWorkflowDifferences(e,t,n,r,i){let a=await j.getInstance().get(K.GET_WORKFLOW_V8_EVENT_LIST,{osClient:e.osClient},e.apiBaseUrl,e);if(a.Code!==1||!Array.isArray(a.Data?.List))throw new Error(`\u83B7\u53D6\u6D41\u7A0B\u4E8B\u4EF6\u540C\u6B65\u72B6\u6001\u5931\u8D25: ${a.Msg||"\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E"}`);let c=new Map(a.Data.List.map(u=>[`${u.FlowDesignId}__${u.NodeId}__${u.EventType}`,u])),l=!1;for(let[u,d]of Object.entries(n.workflowNodeEvents||{})){if(!this.matchesTargetFile(d.filePath,i))continue;let g=c.get(u),m=this.getWorkspaceFilePath(d.filePath);if(!m||!w.existsSync(m))continue;if(!g||!String(g.V8Code||g.Code||"").trim()){let T=this.createRemoteDeletedItem("workflow",`${d.flowName}/${d.nodeName}/${d.eventType}`,u,t,m,d.updateTime);T&&r.push(T);continue}let y=this.normalizeCode(w.readFileSync(m,"utf-8")),f=this.normalizeCode(g.V8Code||g.Code||""),h=this.isLocalModified(m,d.updateTime),S=this.isRemoteNewer(g.UpdateTime,d.updateTime);if(y===f){(h||S)&&g.UpdateTime&&(d.updateTime=g.UpdateTime,this.touchSyncedFile(m,g.UpdateTime),l=!0);continue}let C=this.classifyDifference(h,S,y,f);if(C){let T=`${g.FlowName||d.flowName}/${g.NodeName||d.nodeName}/${g.EventType||d.eventType}`;r.push({kind:"workflow",status:C,name:T,key:u,serverDir:t,filePath:m,localCode:y,remoteCode:f,localUpdateTime:d.updateTime,remoteUpdateTime:g.UpdateTime})}}if(l&&this.saveMeta(n,t),i)return;let p=new Set(Object.keys(n.workflowNodeEvents||{}));for(let u of a.Data.List){let d=`${u.FlowDesignId}__${u.NodeId}__${u.EventType}`,g=u.V8Code||u.Code||"";if(!g.trim()||p.has(d))continue;let m=`${u.FlowName||u.FlowDesignId}/${u.NodeName||u.NodeId}/${u.EventType}`;r.push({kind:"workflow",status:"remoteModified",name:m,key:d,serverDir:t,filePath:this.getRemoteOnlyPlaceholderPath(e,t,"workflow",d),localCode:"",remoteCode:this.normalizeCode(g),localUpdateTime:"",remoteUpdateTime:u.UpdateTime})}}migrateFromFlatMeta(e){let t=R.getInstance();try{let n=t.getSyncRootDir(),r=v.join(n,Ye);if(!w.existsSync(r))return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};let i=t.getWorkspaceRoot();if(!i)return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};let o=JSON.parse(w.readFileSync(r,"utf-8")),a=o.engines||{},c=o.events||{},l={engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}};for(let[p,u]of Object.entries(a)){let d=u;if(d.filePath){let g=v.join(i,d.filePath);v.relative(n,g).split(v.sep)[0]===e&&(l.engines[p]=d)}}for(let[p,u]of Object.entries(c)){let d=u;if(d.filePath){let g=v.join(i,d.filePath);v.relative(n,g).split(v.sep)[0]===e&&(l.events[p]=d)}}return(Object.keys(l.engines).length>0||Object.keys(l.events).length>0)&&this.saveMeta(l,e),l}catch{return{engines:{},events:{},fields:{},menus:{},menuButtons:{},menuScripts:{},workflows:{},workflowNodeEvents:{}}}}async pullEngines(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0){M.warn("Microi: \u6CA1\u6709\u5DF2\u8FDE\u63A5\u7684\u670D\u52A1\u5668\uFF0C\u8BF7\u5148\u5728\u8BBE\u7F6E\u4E2D\u6DFB\u52A0\u8FDE\u63A5\u5E76\u767B\u5F55");return}for(let n of t)try{await this.pullEnginesForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`),M.error(`Microi: \u62C9\u53D6 [${n.label||n.apiBaseUrl}] \u5931\u8D25 - ${i}`)}return}await this.pullEnginesForProfile(e)}async pullEnginesForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE\u4EE3\u7801 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u63A5\u53E3\u5F15\u64CE [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u68C0\u67E5\u540E\u7AEF\u72B6\u6001..."});let a=await n.get(K.GET_STATUS,void 0,r,e);if(a.Code!==1){let A=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u540E\u7AEF\u72B6\u6001\u5F02\u5E38: ${a.Msg||"Code="+a.Code}${A}`)}o.report({message:"\u83B7\u53D6\u7CFB\u7EDF\u914D\u7F6E..."});let l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u}),o.report({message:"\u83B7\u53D6\u63A5\u53E3\u5F15\u64CE\u5217\u8868..."});let g=await n.get(K.GET_ENGINE_LIST,{osClient:i},r,e);if(g.Code!==1){let A=g.Code===1001||g.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u5217\u8868\u5931\u8D25: ${g.Msg||"Code="+g.Code}${A}`)}let{OsClient:m,OsClientType:y,OsClientNetwork:f,List:h,Total:S}=g.Data;if(this.log(`\u83B7\u53D6\u5230 ${S} \u4E2A\u63A5\u53E3\u5F15\u64CE (OsClient: ${m})`),!y||!f)throw new Error(`\u540E\u7AEF\u672A\u8FD4\u56DE\u5B8C\u6574\u7684 OsClientType/OsClientNetwork (OsClient: ${m}, Type: ${y||"\u7A7A"}, Network: ${f||"\u7A7A"})\uFF0C\u65E0\u6CD5\u62C9\u53D6\u4EE3\u7801`);if(y||f){let A={...e,osClientType:y,osClientNetwork:f};await t.addProfile(A)}let C=t.getSyncRootDir(),T=t.buildServerDirName(d,r),k=this.loadMeta(T),E=0,b=0,V=[],z=new Set,F=new Set,I=t.buildOsClientDirName(m,y,f);for(let A of h)try{let D=q(A.Category||"\u672A\u5206\u7C7B"),O=q(A.ApiName||A.ApiEngineKey),J=v.join(C,T,I,Xe,D),Y=q(`${O}(${In(A.ApiEngineKey)}).js`),ue=v.join(J,Y),pe=_n(A.ApiV8Code||"");if(!pe.trim()){b++,w.existsSync(ue)&&this.backupAndDeleteSyncFile(ue,T,"remote-deleted-api"),delete k.engines[A.ApiEngineKey];continue}z.add(A.ApiEngineKey),ge(J),w.writeFileSync(ue,pe,"utf-8");let te=new Date(A.UpdateTime);isNaN(te.getTime())||w.utimesSync(ue,te,te),k.engines[A.ApiEngineKey]={id:A.Id,apiName:A.ApiName,category:D,apiAddress:A.ApiAddress,updateTime:A.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),ue)},E++,o.report({message:`${E}/${S} ${A.ApiEngineKey}`,increment:1/S*100})}catch(D){let O=D instanceof Error?D.message:String(D);F.add(A.ApiEngineKey),V.push(`${A.ApiEngineKey}: ${O}`),this.log(`\u63A5\u53E3\u5F15\u64CE\u6587\u4EF6\u5199\u5165\u5931\u8D25\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u9879 [${A.ApiEngineKey}]: ${O}`)}for(let[A,D]of Object.entries(k.engines)){if(z.has(A)||F.has(A))continue;let O=this.getWorkspaceFilePath(D.filePath);O&&this.backupAndDeleteSyncFile(O,T,"remote-deleted-api"),delete k.engines[A]}this.saveMeta(k,T);let x=d||e.label||r;this.log(`[${x}] \u62C9\u53D6\u5B8C\u6210: ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${b} \u9879\uFF0C\u5931\u8D25 ${V.length} \u9879`),V.length>0?M.warn(`Microi: [${x}] \u5DF2\u62C9\u53D6 ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE\uFF0C${V.length} \u4E2A\u6587\u4EF6\u5931\u8D25\uFF1B\u5931\u8D25\u660E\u7EC6\u5DF2\u5199\u5165 Microi \u8F93\u51FA\u3002`):M.info(`Microi: [${x}] \u6210\u529F\u62C9\u53D6 ${E} \u4E2A\u63A5\u53E3\u5F15\u64CE${b>0?`\uFF08\u8DF3\u8FC7 ${b} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)})}async pullEvents(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0)return;for(let n of t)try{await this.pullEventsForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6V8\u4E8B\u4EF6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`)}return}await this.pullEventsForProfile(e)}async pullEventsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6V8\u4E8B\u4EF6\u4EE3\u7801 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6V8\u4E8B\u4EF6 [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6V8\u4E8B\u4EF6\u5217\u8868..."});let a=await n.get(K.GET_EVENT_LIST,{osClient:i},r,e);if(a.Code!==1){let I=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6V8\u4E8B\u4EF6\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}${I}`)}let{List:c,Total:l}=a.Data;this.log(`\u83B7\u53D6\u5230 ${l} \u4E2AV8\u4E8B\u4EF6`);let u=await Ce.getInstance().getSysConfig(r,i),d=u?.SysShortTitle||"",g=u?.SysTitle||"",m=d||g||u?.CompanyName||e.label||"";m&&(m!==e.label||d!==e.sysShortTitle||g!==e.sysTitle)&&await t.addProfile({...e,label:m,sysShortTitle:d,sysTitle:g});let y=t.getSyncRootDir(),f=t.buildServerDirName(m,r),h=this.loadMeta(f),S=0,C=0,T=0,k=new Set(c.map(I=>`${I.FormEngineKey}__${I.EventType}`)),b=t.getProfiles().find(I=>I.apiBaseUrl===e.apiBaseUrl&&I.osClient===e.osClient)||e;if(!b.osClientType||!b.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE\u4EE5\u83B7\u53D6\u5B8C\u6574\u914D\u7F6E");let V=t.buildOsClientDirName(i,b.osClientType,b.osClientNetwork),z={SubmitBeforeServerV8:"\u540E\u7AEF\u63D0\u4EA4\u524DV8\u4E8B\u4EF6",SubmitAfterServerV8:"\u540E\u7AEF\u63D0\u4EA4\u540EV8\u4E8B\u4EF6",SubmitFormV8:"\u524D\u7AEF\u8868\u5355\u63D0\u4EA4V8\u4E8B\u4EF6",OutFormV8:"\u524D\u7AEF\u8868\u5355\u9000\u51FAV8\u4E8B\u4EF6",ServerDataV8:"\u540E\u7AEF\u6570\u636EV8\u4E8B\u4EF6"};for(let I of c){let x=I.V8Code||"",A=q(I.Description?`${I.Description}\uFF08${I.FormEngineKey}\uFF09`:I.FormEngineKey),D=or[I.EventType]||I.EventType,O=q(`${D}\uFF08${I.EventType}\uFF09`)+".js",J=v.join(y,f,V,Ve,A,$t);ge(J);let Y=v.join(J,O),ue=z[I.EventType];if(ue){let he=q(`${ue}\uFF08${I.EventType}\uFF09`)+".js",le=v.join(J,he);le!==Y&&w.existsSync(le)&&!this.isLocalModified(le,I.UpdateTime)&&(w.existsSync(Y)?w.unlinkSync(le):w.renameSync(le,Y))}let pe=`${I.FormEngineKey}__${I.EventType}`;if(h.events[pe]={id:I.Id,formEngineKey:I.FormEngineKey,description:I.Description||"",eventType:I.EventType,updateTime:I.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),Y)},!x.trim()){w.existsSync(Y)&&this.backupAndDeleteSyncFile(Y,f,"remote-deleted-form-event"),T++,S++,o.report({message:`${S}/${l}`,increment:l>0?1/l*100:void 0});continue}w.writeFileSync(Y,x,"utf-8");let te=new Date(I.UpdateTime);isNaN(te.getTime())||w.utimesSync(Y,te,te),C++,S++,o.report({message:`${S}/${l}`,increment:l>0?1/l*100:void 0})}for(let[I,x]of Object.entries(h.events)){if(k.has(I))continue;let A=this.getWorkspaceFilePath(x.filePath);A&&this.backupAndDeleteSyncFile(A,f,"remote-deleted-form-event"),delete h.events[I]}this.saveMeta(h,f);let F=m||e.label||r;this.log(`[${F}] \u62C9\u53D6\u5B8C\u6210: ${C} \u4E2AV8\u4E8B\u4EF6\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${T} \u9879`),M.info(`Microi: [${F}] \u6210\u529F\u62C9\u53D6 ${C} \u4E2AV8\u4E8B\u4EF6\u6587\u4EF6${T>0?`\uFF08\u8DF3\u8FC7 ${T} \u4E2A\u7A7A\u4EE3\u7801\u4E8B\u4EF6\uFF09`:""}`)})}async pullWorkflows(e){if(!e){let t=R.getInstance().getProfiles();if(t.length===0)return;for(let n of t)try{await this.pullWorkflowsForProfile(n)}catch(r){let i=r instanceof Error?r.message:String(r);this.log(`\u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${i}`)}return}await this.pullWorkflowsForProfile(e)}async pullWorkflowsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE\u8282\u70B9 V8 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u6D41\u7A0B\u5F15\u64CE [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6\u6D41\u7A0B\u8282\u70B9V8\u5217\u8868..."});let a=await n.get(K.GET_WORKFLOW_V8_EVENT_LIST,{osClient:i},r,e);if(a.Code!==1){let D=a.Code===1001||a.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u6D41\u7A0B\u8282\u70B9V8\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}${D}`)}let l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u});let m=t.getProfiles().find(D=>D.apiBaseUrl===e.apiBaseUrl&&D.osClient===e.osClient)||e;if(!m.osClientType||!m.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let y=a.Data.OsClient||i,f=t.buildServerDirName(d,r),h=t.buildOsClientDirName(y,m.osClientType,m.osClientNetwork),S=t.getSyncRootDir(),C=this.loadMeta(f);C.workflows||(C.workflows={}),C.workflowNodeEvents||(C.workflowNodeEvents={});let T=a.Data.Flows||[],k=a.Data.Nodes||[],E=a.Data.Lines||[],b=a.Data.List||[],V=new Map(T.map(D=>[String(D.Id||""),D])),z=new Set(T.map(D=>String(D.Id||"")).filter(Boolean)),F=new Set(b.filter(D=>String(D.V8Code||D.Code||"").trim()).map(D=>`${D.FlowDesignId}__${D.NodeId}__${D.EventType}`)),I=0,x=0;for(let D of T){let O=String(D.Id||"");if(!O)continue;let J=String(D.FlowName||O),Y=String(D.UpdateTime||we()),ue=v.join(S,f,h,Ze,q(`${J}\uFF08${O}\uFF09`));ge(ue);let pe=k.filter(le=>String(le.FlowDesignId||"")===O),te=E.filter(le=>String(le.FlowDesignId||"")===O),he=v.join(ue,"\u6D41\u7A0B\u8BBE\u8BA1\u56FE\uFF08WF_FlowDesign\uFF09.json");w.writeFileSync(he,JSON.stringify({FlowDesign:D,Nodes:pe,Lines:te},null,2),"utf-8"),this.touchSyncedFile(he,Y),C.workflows[O]={flowDesignId:O,flowName:J,updateTime:Y,filePath:v.relative(t.getWorkspaceRoot(),he)}}for(let D of b){let O=String(D.FlowDesignId||""),J=String(D.NodeId||""),Y=String(D.EventType||"");if(!O||!J||!Y)continue;let ue=V.get(O),pe=String(D.FlowName||ue?.FlowName||O),te=String(D.NodeName||J),he=ar[Y]||D.EventName||Y,le=v.join(S,f,h,Ze,q(`${pe}\uFF08${O}\uFF09`),Lt,q(`${te}\uFF08${J}\uFF09`));ge(le);let N=v.join(le,q(`${he}\uFF08${Y}\uFF09`)+".js"),me=D.V8Code||D.Code||"",se=String(D.UpdateTime||ue?.UpdateTime||we());if(C.workflowNodeEvents[`${O}__${J}__${Y}`]={flowDesignId:O,flowName:pe,nodeId:J,nodeName:te,eventType:Y,updateTime:se,filePath:v.relative(t.getWorkspaceRoot(),N)},!me.trim()){w.existsSync(N)&&this.backupAndDeleteSyncFile(N,f,"remote-deleted-workflow-event"),x++,o.report({message:`${I}/${b.length} ${pe}/${te}`});continue}w.writeFileSync(N,me,"utf-8"),this.touchSyncedFile(N,se),I++,o.report({message:`${I}/${b.length} ${pe}/${te}`})}for(let[D,O]of Object.entries(C.workflowNodeEvents)){if(F.has(D))continue;let J=this.getWorkspaceFilePath(O.filePath);J&&this.backupAndDeleteSyncFile(J,f,"remote-deleted-workflow-event"),delete C.workflowNodeEvents[D]}for(let[D,O]of Object.entries(C.workflows)){if(z.has(D))continue;let J=this.getWorkspaceFilePath(O.filePath);J&&this.backupAndDeleteSyncFile(J,f,"remote-deleted-workflow"),delete C.workflows[D]}this.saveMeta(C,f);let A=d||e.label||r;this.log(`[${A}] \u6D41\u7A0B\u5F15\u64CE\u62C9\u53D6\u5B8C\u6210: ${T.length} \u4E2A\u6D41\u7A0B\uFF0C${I} \u4E2A\u8282\u70B9V8\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${x} \u9879`),M.info(`Microi: [${A}] \u6210\u529F\u62C9\u53D6 ${T.length} \u4E2A\u6D41\u7A0B\u3001${I} \u4E2A\u6D41\u7A0B\u8282\u70B9V8\u6587\u4EF6${x>0?`\uFF08\u8DF3\u8FC7 ${x} \u4E2A\u7A7A\u4EE3\u7801\u4E8B\u4EF6\uFF09`:""}`)})}findProfileByServerDir(e){let t=R.getInstance(),n=t.getProfiles();for(let r of n)if(t.buildServerDirName(r.label,r.apiBaseUrl)===e)return r}hasSyncBaseline(e,t){let n=v.resolve(e).toLowerCase(),r=this.loadMeta(t);return[r.engines,r.events,r.fields||{},r.menuButtons||{},r.menuScripts||{},r.workflowNodeEvents||{}].some(o=>Object.values(o).some(a=>{let c=this.getWorkspaceFilePath(a.filePath);return!!c&&v.resolve(c).toLowerCase()===n}))}async runPushPreflight(e,t,n,r){if(!n){let i=`\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u6240\u5C5E\u670D\u52A1\u5668\u914D\u7F6E\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\uFF1A${e}`;return this.log(i),M.error(`Microi: ${i}`),!1}if(!this.hasSyncBaseline(e,t)){let i=`\u6587\u4EF6\u6CA1\u6709\u540C\u6B65\u57FA\u7EBF\uFF0C\u65E0\u6CD5\u786E\u8BA4\u670D\u52A1\u5668\u7AEF\u662F\u5426\u66F4\u65B0\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u3002\u8BF7\u5148\u62C9\u53D6\u5BF9\u5E94\u5F15\u64CE\uFF1A${e}`;return this.log(i),M.error(`Microi: ${i}`),!1}try{let i=await this.checkRemoteDifferences(n,r,e),o=v.resolve(e).toLowerCase(),a=i.find(p=>v.resolve(p.filePath).toLowerCase()===o);if(!a||a.status==="localModified")return!0;let l=`${a.status==="conflict"?"\u672C\u5730\u4E0E\u670D\u52A1\u5668\u5747\u5DF2\u4FEE\u6539":a.status==="remoteDeleted"?"\u670D\u52A1\u5668\u7AEF\u8D44\u6E90\u5DF2\u5220\u9664":"\u670D\u52A1\u5668\u4EE3\u7801\u8F83\u65B0"}\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u4EE5\u907F\u514D\u8986\u76D6\u3002\u8BF7\u5728\u201C\u540C\u6B65\u7ED3\u679C\u201D\u4E2D\u67E5\u770B\u5DEE\u5F02\u5E76\u62C9\u53D6\u6216\u5408\u5E76\uFF1A${a.name}`;return this.log(l),M.error(`Microi: ${l}`),!1}catch(i){let o=i instanceof Error?i.message:String(i);return this.log(`\u63A8\u9001\u524D\u540C\u6B65\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\uFF1A${o}`),M.error(`Microi: \u63A8\u9001\u524D\u540C\u6B65\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001 - ${o}`),!1}}async pushFile(e,t={}){let r=R.getInstance().getSyncRootDir();if(v.extname(e).toLowerCase()===".js"&&w.existsSync(e)){let u=yr(_e(w.readFileSync(e,"utf-8")));if(u.length>0){let d=u[0],g=`\u68C0\u6D4B\u5230 AI/\u7EC8\u7AEF\u5DE5\u5177\u8F93\u51FA\u6C61\u67D3\uFF08\u7B2C ${d.line} \u884C: ${d.marker}\uFF09\uFF0C\u5DF2\u505C\u6B62\u63A8\u9001\u3002\u8BF7\u6062\u590D\u5B8C\u6574\u6E90\u7801\u540E\u518D\u8BD5\uFF1A${e}`;return this.log(g),M.error(`Microi: ${g}`),!1}}let i=gr(e,r);if(i){let u=this.findProfileByServerDir(i.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,i.serverDir,u,"api")?!1:this.pushEngineFile(e,i,u)}let o=pr(e,r);if(o){let u=this.findProfileByServerDir(o.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,o.serverDir,u,"form")?!1:this.pushEventFile(e,o,u)}let a=mr(e,r);if(a){let u=this.findProfileByServerDir(a.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,a.serverDir,u,"form")?!1:this.pushFieldFile(e,a,u)}let c=fr(e,r);if(c){let u=this.findProfileByServerDir(c.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,c.serverDir,u,"module")?!1:this.pushMenuButtonFile(e,c,u)}let l=hr(e,r);if(l){let u=this.findProfileByServerDir(l.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,l.serverDir,u,"module")?!1:this.pushMenuScriptFile(e,l,u)}let p=Sr(e,r);if(p){let u=this.findProfileByServerDir(p.serverDir);return!t.skipPreflight&&!await this.runPushPreflight(e,p.serverDir,u,"workflow")?!1:this.pushWorkflowNodeFile(e,p,u)}return this.log(`\u65E0\u6CD5\u89E3\u6790\u6587\u4EF6\u8DEF\u5F84: ${e}`),!1}async pushEngineFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001\u63A5\u53E3\u5F15\u64CE: ${t.apiEngineKey}...`);try{let a="",c="";try{let g=await r.post(K.GET_ENGINE_CODE,{OsClient:t.osClient,ApiEngineKey:t.apiEngineKey},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.ApiV8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"ApiEngine",key:t.apiEngineKey,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001\u63A5\u53E3\u5F15\u64CE ${t.apiEngineKey}`}),u={OsClient:t.osClient,ApiEngineKey:t.apiEngineKey,ApiV8CodeBase64:Buffer.from(p.code,"utf8").toString("base64")};l||(u.Version=p.version,u.ChangeSummary=p.changeHistory);let d=await r.post(K.UPDATE_ENGINE_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.apiEngineKey}`);let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir);if(l?delete m.engines[t.apiEngineKey]:m.engines[t.apiEngineKey]&&(m.engines[t.apiEngineKey].updateTime=g),this.saveMeta(m,t.serverDir),l)w.existsSync(e)&&w.unlinkSync(e);else{w.writeFileSync(e,p.code,"utf-8");let y=new Date(g);isNaN(y.getTime())||w.utimesSync(e,y,y)}return!0}else return this.log(`\u63A8\u9001\u5931\u8D25: ${t.apiEngineKey} - ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u5F02\u5E38: ${t.apiEngineKey} - ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async pushEventFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001V8\u4E8B\u4EF6: ${t.formEngineKey}/${t.eventType}...`);try{let a="",c="";try{let g=await r.post(K.GET_EVENT_CODE,{OsClient:t.osClient,FormEngineKey:t.formEngineKey,EventType:t.eventType},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.V8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"V8Event",key:t.formEngineKey,eventType:t.eventType,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001 V8 \u4E8B\u4EF6 ${t.formEngineKey}/${t.eventType}`}),u={OsClient:t.osClient,FormEngineKey:t.formEngineKey,EventType:t.eventType,V8Code:p.code};l||(u.Version=p.version,u.ChangeHistory=p.changeHistory);let d=await r.post(K.UPDATE_EVENT_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.formEngineKey}/${t.eventType}`);let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir),y=`${t.formEngineKey}__${t.eventType}`;if(l)delete m.events[y];else{let f=m.events[y];m.events[y]={id:f?.id||"",formEngineKey:t.formEngineKey,description:f?.description||"",eventType:t.eventType,updateTime:g,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}}if(this.saveMeta(m,t.serverDir),l)w.existsSync(e)&&w.unlinkSync(e);else{w.writeFileSync(e,p.code,"utf-8");let f=new Date(g);isNaN(f.getTime())||w.utimesSync(e,f,f)}return!0}else return this.log(`\u63A8\u9001\u5931\u8D25: ${t.formEngineKey}/${t.eventType} - ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u5F02\u5E38: ${t.formEngineKey}/${t.eventType} - ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async createEngine(e){let t=j.getInstance(),n=R.getInstance();this.log(`\u521B\u5EFA\u63A5\u53E3\u5F15\u64CE: ${e.apiEngineKey}...`);try{let r=bt({kind:"ApiEngine",key:e.apiEngineKey,currentCode:"",functionDescription:`\u63A5\u53E3\u5F15\u64CE ${e.apiName} \u7684\u5B8C\u6574\u4E1A\u52A1\u903B\u8F91\u3002`,changeSummary:`\u901A\u8FC7 VS Code \u521B\u5EFA\u63A5\u53E3\u5F15\u64CE ${e.apiEngineKey}`,initial:!0}),i=await t.post(K.CREATE_ENGINE,{OsClient:e.profile.osClient,ApiName:e.apiName,ApiEngineKey:e.apiEngineKey,ApiAddress:e.apiAddress||"",ApiRemark:e.apiRemark||"",Lock:e.lock?1:0,LockKey:e.lockKey||"",AllowAnonymous:e.allowAnonymous?1:0,V8Limit:e.v8Limit?1:0,IsEnable:e.isEnable!==!1?1:0,ApiRole:e.apiRole||"",Category:e.category||"\u672A\u5206\u7C7B",ApiV8CodeBase64:Buffer.from(r.code,"utf8").toString("base64"),Version:r.version,ChangeSummary:r.changeHistory},void 0,e.profile.apiBaseUrl,e.profile);if(i.Code===1){let o=n.getSyncRootDir(),a=n.buildServerDirName(e.profile.label,e.profile.apiBaseUrl),c=n.buildOsClientDirName(e.profile.osClient,e.profile.osClientType,e.profile.osClientNetwork),l=q(e.category||"\u672A\u5206\u7C7B"),p=q(e.apiName||e.apiEngineKey),u=v.join(o,a,c,Xe,l);ge(u);let d=v.join(u,q(`${p}(${In(e.apiEngineKey)}).js`));w.writeFileSync(d,r.code,"utf-8");let g=this.loadMeta(a);return g.engines[e.apiEngineKey]={id:"",apiName:e.apiName,category:l,apiAddress:e.apiAddress||"",updateTime:we(),filePath:v.relative(n.getWorkspaceRoot(),d)},this.saveMeta(g,a),this.log(`\u521B\u5EFA\u6210\u529F: ${e.apiEngineKey}`),M.info(`Microi: \u63A5\u53E3\u5F15\u64CE [${e.apiEngineKey}] \u521B\u5EFA\u6210\u529F`),await fe.showTextDocument(tr.file(d)),!0}else return this.log(`\u521B\u5EFA\u5931\u8D25: ${e.apiEngineKey} - ${i.Msg}`),M.error(`Microi: \u521B\u5EFA\u5931\u8D25 - ${i.Msg}`),!1}catch(r){let i=r instanceof Error?r.message:String(r);return this.log(`\u521B\u5EFA\u5F02\u5E38: ${e.apiEngineKey} - ${i}`),M.error(`Microi: \u521B\u5EFA\u5F02\u5E38 - ${i}`),!1}}async pullFields(e){if(!e){let t=R.getInstance().getProfiles();for(let n of t)try{await this.pullFieldsForProfile(n)}catch(r){this.log(`\u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${r instanceof Error?r.message:String(r)}`)}return}await this.pullFieldsForProfile(e)}async pullFieldsForTableFolder(e){let n=R.getInstance().getSyncRootDir(),r=v.relative(n,e).split(v.sep);if(r.length<4||r[2]!==Ve){M.warn("Microi: \u8BF7\u5728\u201C\u8868\u5355\u5F15\u64CE\u201D\u4E0B\u7684\u8868\u76EE\u5F55\u6267\u884C\u5B57\u6BB5 V8 \u4E8B\u4EF6\u62C9\u53D6");return}let i=a=>{let c=a.match(/[((]([^))]+)[))]\s*$/);return c?c[1]:a},o=this.findProfileByServerDir(r[0]);if(!o){M.error(`Microi: \u672A\u627E\u5230\u4E0E\u76EE\u5F55 "${r[0]}" \u5339\u914D\u7684\u670D\u52A1\u5668\u8FDE\u63A5`);return}await this.pullFieldsForTable(o,i(r[3]),e,r[0])}async pullFieldsForTable(e,t,n,r){let i=R.getInstance(),o=j.getInstance(),a=this.loadMeta(r);a.fields||(a.fields={}),this.log(`\u62C9\u53D6\u8868\u5B57\u6BB5V8\u4E8B\u4EF6: ${t}...`);let c=await o.get(K.GET_FIELD_LIST,{osClient:e.osClient,tableName:t},e.apiBaseUrl,e);if(c.Code!==1){M.error(`Microi: \u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 - ${c.Msg}`);return}let l=c.Data.List||[],p=["V8Code","KeyupV8Code","V8TmpEngineTable","V8TmpEngineForm"],u=0,d=0;for(let g of l){let m=q(g.Label?`${g.Label}\uFF08${g.Name}\uFF09`:g.Name),y=v.join(n,St,m);for(let f of p){let h=(g[f]||"").toString(),S=Sn[f]||f,C=q(`${S}\uFF08${f}\uFF09`)+".js",T=v.join(y,C),k=`${t}__${g.Name}__${f}`;if(!h.trim()){d++,w.existsSync(T)&&w.unlinkSync(T),delete a.fields[k];continue}ge(y),w.writeFileSync(T,h,"utf-8");let E=new Date(g.UpdateTime);isNaN(E.getTime())||w.utimesSync(T,E,E),a.fields[k]={fieldId:g.Id,tableId:g.TableId,tableName:t,fieldName:g.Name,fieldLabel:g.Label||"",v8Key:f,updateTime:g.UpdateTime,filePath:v.relative(i.getWorkspaceRoot(),T)},u++}}this.saveMeta(a,r),M.info(`Microi: \u5DF2\u62C9\u53D6 ${t} \u7684 ${u} \u4E2A\u5B57\u6BB5V8\u4E8B\u4EF6\u6587\u4EF6${d>0?`\uFF08\u8DF3\u8FC7 ${d} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)}async pullFieldsForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u5168\u91CF\u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6 [${e.label||r}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u5B57\u6BB5V8\u4E8B\u4EF6 [${e.label||r}]`,cancellable:!1},async o=>{o.report({message:"\u83B7\u53D6\u8868\u5217\u8868..."});let a=await n.get(K.GET_DB_SCHEMA,{osClient:i},r,e);if(a.Code!==1)throw new Error(`\u83B7\u53D6\u8868\u5217\u8868\u5931\u8D25: ${a.Msg||"Code="+a.Code}`);let c=a.Data.Tables||[],p=await Ce.getInstance().getSysConfig(r,i),u=p?.SysShortTitle||"",d=p?.SysTitle||"",g=u||d||e.label||"",m=t.buildServerDirName(g,r),y=this.loadMeta(m);y.fields||(y.fields={});let h=t.getProfiles().find(F=>F.apiBaseUrl===e.apiBaseUrl&&F.osClient===e.osClient)||e;if(!h.osClientType||!h.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let S=t.buildOsClientDirName(i,h.osClientType,h.osClientNetwork),C=t.getSyncRootDir(),T=["V8Code","KeyupV8Code","V8TmpEngineTable","V8TmpEngineForm"],k=0,E=0,b=0,V=new Set,z=new Set;for(let F of c){b++,o.report({message:`[${b}/${c.length}] ${F.Name}`});let I=await n.get(K.GET_FIELD_LIST,{osClient:i,tableId:F.Id},r,e);if(I.Code!==1){z.add(F.Name.toLowerCase()),this.log(` \u8DF3\u8FC7\u8868 ${F.Name}: ${I.Msg}`);continue}let x=I.Data.List||[],A=q(F.Description?`${F.Description}\uFF08${F.Name}\uFF09`:F.Name);for(let D of x)for(let O of T){let J=(D[O]||"").toString();if(!J.trim()){E++;continue}let Y=q(D.Label?`${D.Label}\uFF08${D.Name}\uFF09`:D.Name),ue=Sn[O]||O,pe=q(`${ue}\uFF08${O}\uFF09`)+".js",te=v.join(C,m,S,Ve,A,St,Y);ge(te);let he=v.join(te,pe);w.writeFileSync(he,J,"utf-8");let le=new Date(D.UpdateTime);isNaN(le.getTime())||w.utimesSync(he,le,le);let N=`${F.Name}__${D.Name}__${O}`;V.add(N),y.fields[N]={fieldId:D.Id,tableId:D.TableId,tableName:F.Name,fieldName:D.Name,fieldLabel:D.Label||"",v8Key:O,updateTime:D.UpdateTime,filePath:v.relative(t.getWorkspaceRoot(),he)},k++}}for(let[F,I]of Object.entries(y.fields)){if(V.has(F)||z.has(I.tableName.toLowerCase()))continue;let x=this.getWorkspaceFilePath(I.filePath);x&&this.backupAndDeleteSyncFile(x,m,"remote-deleted-field-event"),delete y.fields[F]}this.saveMeta(y,m),this.log(`\u5B57\u6BB5V8\u4E8B\u4EF6\u62C9\u53D6\u5B8C\u6210: ${k} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u7A7A\u4EE3\u7801 ${E} \u9879`),M.info(`Microi: \u6210\u529F\u62C9\u53D6 ${k} \u4E2A\u5B57\u6BB5V8\u4E8B\u4EF6${E>0?`\uFF08\u8DF3\u8FC7 ${E} \u4E2A\u7A7A\u4EE3\u7801\uFF09`:""}`)})}async pushFieldFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u5B57\u6BB5V8\u4E8B\u4EF6: ${t.tableName}/${t.fieldName}/${t.v8Key}...`);try{let o=await r.post(K.UPDATE_FIELD,{OsClient:t.osClient,TableName:t.tableName,Name:t.fieldName,[t.v8Key]:i},void 0,n?.apiBaseUrl,n);if(o.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.tableName}/${t.fieldName}/${t.v8Key}`);let a=this.loadMeta(t.serverDir),c=`${t.tableName}__${t.fieldName}__${t.v8Key}`;a.fields||(a.fields={});let l=o.Data?.UpdateTime||we();return i.trim()?a.fields[c]={fieldId:a.fields[c]?.fieldId||"",tableId:a.fields[c]?.tableId||"",tableName:t.tableName,fieldName:t.fieldName,fieldLabel:a.fields[c]?.fieldLabel||"",v8Key:t.v8Key,updateTime:l,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}:delete a.fields[c],this.saveMeta(a,t.serverDir),i.trim()?this.touchSyncedFile(e,l):w.existsSync(e)&&w.unlinkSync(e),!0}return this.log(`\u63A8\u9001\u5931\u8D25: ${o.Msg}`),M.error(`Microi: \u63A8\u9001\u5B57\u6BB5V8\u4E8B\u4EF6\u5931\u8D25 - ${o.Msg}`),!1}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${a}`),!1}}async pullMenuButtons(e){if(!e){let t=R.getInstance().getProfiles();for(let n of t)try{await this.pullMenuButtonsForProfile(n)}catch(r){this.log(`\u62C9\u53D6\u83DC\u5355\u6309\u94AE\u5931\u8D25 [${n.label||n.apiBaseUrl}]: ${r instanceof Error?r.message:String(r)}`)}return}await this.pullMenuButtonsForProfile(e)}async pullMenuButtonsForModuleFolder(e){let n=R.getInstance().getSyncRootDir(),r=v.relative(n,e).split(v.sep);if(r.length<4||r[2]!==je){M.warn("Microi: \u8BF7\u5728\u201C\u6A21\u5757\u5F15\u64CE\u201D\u4E0B\u7684\u6A21\u5757\u76EE\u5F55\u6267\u884C\u62C9\u53D6");return}let i=this.findProfileByServerDir(r[0]);if(!i){M.error(`Microi: \u672A\u627E\u5230\u4E0E\u76EE\u5F55 "${r[0]}" \u5339\u914D\u7684\u670D\u52A1\u5668\u8FDE\u63A5`);return}let o=this.extractTrailingKey(v.basename(e));await this.pullMenuButtonsForProfile(i,o,r[0],r[1],e)}async pullMenuButtonsForProfile(e,t,n,r,i){let o=R.getInstance(),a=j.getInstance(),c=e.apiBaseUrl,l=e.osClient;this.log(`\u5F00\u59CB\u62C9\u53D6\u6A21\u5757 Join/Where \u4E0E\u6309\u94AE V8 \u4EE3\u7801 [${e.label||c}]...`),await fe.withProgress({location:qe.Notification,title:`Microi: \u62C9\u53D6\u6A21\u5757\u4EE3\u7801 [${e.label||c}]`,cancellable:!1},async p=>{let u=await a.get(K.LIST_MODULES,{osClient:l},c,e);if(u.Code!==1)throw new Error(`\u83B7\u53D6\u6A21\u5757\u5217\u8868\u5931\u8D25: ${u.Msg}`);let d=u.Data.List||[],m=await Ce.getInstance().getSysConfig(c,l),y=m?.SysShortTitle||"",f=m?.SysTitle||"",h=y||f||e.label||"",S=n||o.buildServerDirName(h,c),C=this.loadMeta(S);C.menus||(C.menus={}),C.menuButtons||(C.menuButtons={}),C.menuScripts||(C.menuScripts={});let k=o.getProfiles().find(N=>N.apiBaseUrl===e.apiBaseUrl&&N.osClient===e.osClient)||e;if(!k.osClientType||!k.osClientNetwork)throw new Error("\u7F3A\u5C11 OsClientType/OsClientNetwork\uFF0C\u8BF7\u5148\u62C9\u53D6\u63A5\u53E3\u5F15\u64CE");let E=r||o.buildOsClientDirName(l,k.osClientType,k.osClientNetwork),b=o.getSyncRootDir(),V=v.join(b,S,E,je),z=Object.keys(et),F=Object.keys(Ct),I=0,x=0,A=0,D=0,O=0,J=new Map(d.map(N=>[N.Id,N])),Y=new Map,ue=N=>N||"";for(let N of d){let me=ue(N.ParentId);Y.has(me)||Y.set(me,[]),Y.get(me).push(N)}let pe=N=>N.sort((me,se)=>{let ye=typeof me.Sort=="number"?me.Sort:0,ft=typeof se.Sort=="number"?se.Sort:0;return ye!==ft?ye-ft:String(me.Name||me.Label||"").localeCompare(String(se.Name||se.Label||""))}),te=t?J.get(t)?[J.get(t)]:[]:pe(d.filter(N=>!N.ParentId||!J.has(N.ParentId)));if(t&&te.length===0)throw new Error(`\u627E\u4E0D\u5230\u6A21\u5757 Id=${t}`);let he=t?i||v.join(V,q(`${te[0].Label||te[0].Name||te[0].Id}\uFF08${te[0].Id}\uFF09`)):V;if(this.backupExistingTree(he,S,t?"module-subtree":"module-engine"),!t)C.menus={},C.menuButtons={},C.menuScripts={};else{let N=new Set,me=se=>{if(!N.has(se)){N.add(se);for(let ye of Y.get(se)||[])me(ye.Id)}};me(t);for(let se of N)delete C.menus[se];for(let[se,ye]of Object.entries(C.menuButtons))N.has(ye.moduleId)&&delete C.menuButtons[se];for(let[se,ye]of Object.entries(C.menuScripts))N.has(ye.moduleId)&&delete C.menuScripts[se]}let le=async(N,me)=>{D++,p.report({message:`[${D}/${d.length}] ${N.Name||N.Label}`});let se=N.Label||N.Name||N.Id,ye=v.join(me,q(`${se}\uFF08${N.Id}\uFF09`));ge(ye);let ft=pe(Y.get(N.Id)||[]);if(ft.length>0){for(let de of ft)await le(de,ye);return}let gn=await a.get(K.GET_MODULE,{osClient:l,moduleId:N.Id},c,e);if(gn.Code!==1){this.log(` \u8DF3\u8FC7\u6A21\u5757 ${N.Name}: ${gn.Msg}`);return}let pn=gn.Data,Le=String(pn.UpdateTime||we()),Jn={};for(let de of F){let Vt=String(pn[de]||""),mn=Ct[de]||de,Be=v.join(ye,q(`${mn}\uFF08${de}\uFF09`)+".js");w.writeFileSync(Be,Vt,"utf-8"),this.touchSyncedFile(Be,Le),C.menuScripts[this.getMenuScriptMetaKey(N.Id,de)]={moduleId:N.Id,moduleName:se,scriptField:de,codeHash:this.sourceHash(Vt),updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),Be)},A++}for(let de of z){let Vt=et[de]||de,mn=q(`${Vt}\uFF08${de}\uFF09`),Be=v.join(ye,mn);ge(Be),x++;let xt=pn[de],Ge=[];if(xt)try{Ge=typeof xt=="string"?JSON.parse(xt):xt,Array.isArray(Ge)||(Ge=[])}catch{this.log(` \u6309\u94AE JSON \u89E3\u6790\u5931\u8D25 ${N.Name}.${de}`),Ge=[]}let ys=[...Ge].sort((ze,ke)=>String(ze.Id||"").localeCompare(String(ke.Id||"")));Jn[de]=require("crypto").createHash("sha1").update(JSON.stringify(ys)).digest("hex");for(let ze of Ge){let ke=String(ze.Id||""),Ot=String(ze.Name||ke||"Unknown");if(!ke)continue;let qn=String(ze.V8Code||""),fn=v.join(Be,q(`${Ot}\uFF08${ke}\uFF09`)+".js");C.menuButtons[this.getMenuButtonMetaKey(N.Id,de,ke,"V8Code")]={moduleId:N.Id,moduleName:se,btnField:de,btnId:ke,btnName:Ot,v8SubField:"V8Code",updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),fn)},qn.trim()?(w.writeFileSync(fn,qn,"utf-8"),this.touchSyncedFile(fn,Le),I++):O++;let Qn=String(ze.V8CodeShow||"");if(Qn.trim()){let hn=v.join(Be,q(`${Ot}_\u663E\u9690\u5224\u65AD\uFF08${ke}\uFF09`)+".js");w.writeFileSync(hn,Qn,"utf-8"),this.touchSyncedFile(hn,Le),C.menuButtons[this.getMenuButtonMetaKey(N.Id,de,ke,"V8CodeShow")]={moduleId:N.Id,moduleName:se,btnField:de,btnId:ke,btnName:Ot,v8SubField:"V8CodeShow",updateTime:Le,filePath:v.relative(o.getWorkspaceRoot(),hn)},I++}else O++}}C.menus[N.Id]={moduleId:N.Id,moduleName:se,updateTime:Le,buttonHashes:Jn}};ge(V);for(let N of te)await le(N,V);this.saveMeta(C,S),this.log(`\u6A21\u5757\u4EE3\u7801\u62C9\u53D6\u5B8C\u6210: ${I} \u4E2A\u6309\u94AEV8\u6587\u4EF6\uFF0C${A} \u4E2A Join/Where \u6587\u4EF6\uFF0C${x} \u4E2A\u6309\u94AE\u76EE\u5F55\uFF0C\u8DF3\u8FC7\u7A7A\u6309\u94AE\u4EE3\u7801 ${O} \u9879`),M.info(`Microi: \u6210\u529F\u62C9\u53D6 ${I} \u4E2A\u6309\u94AEV8\u6587\u4EF6\u548C ${A} \u4E2A Join/Where \u6587\u4EF6${O>0?`\uFF08\u8DF3\u8FC7 ${O} \u4E2A\u7A7A\u6309\u94AE\u4EE3\u7801\uFF09`:""}\uFF0C\u5DF2\u751F\u6210 ${x} \u4E2A\u6309\u94AE\u76EE\u5F55`)})}backupExistingTree(e,t,n){if(!w.existsSync(e))return;let i=R.getInstance().getSyncRootDir();this.ensureSyncGitExcludes(i);let o=v.join(i,".backups",n,this.shortBackupKey(t));ge(o);let a=v.join(o,`${Date.now()}-${this.shortBackupKey(v.basename(e))}`);w.renameSync(e,a)}backupAndDeleteSyncFile(e,t,n){if(!w.existsSync(e))return;let r=R.getInstance(),i=r.getSyncRootDir();this.ensureSyncGitExcludes(i);let o=r.getWorkspaceRoot()||i,c=v.relative(o,e).split(v.sep).filter(u=>u&&u!=="..").map(q),l=v.join(i,".backups",n,this.shortBackupKey(t),String(Date.now())),p=v.join(l,...c.length?c:[q(v.basename(e))]);ge(v.dirname(p)),w.copyFileSync(e,p),w.unlinkSync(e)}async pushMenuScriptFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u6A21\u5757\u811A\u672C: ${t.moduleId}.${t.scriptField}...`);try{let o=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n);if(o.Code!==1||!o.Data)return M.error(`Microi: \u63A8\u9001\u5931\u8D25 - \u62C9\u53D6\u6A21\u5757\u5931\u8D25 ${o.Msg}`),!1;let a=o.Data,c=String(a[t.scriptField]||""),l=R.getInstance(),p=l.getSyncRootDir();this.ensureSyncGitExcludes(p);let u=v.join(p,".backups","menu-script",this.shortBackupKey(t.serverDir),t.moduleId);ge(u),w.writeFileSync(v.join(u,`${t.scriptField}-${Date.now()}.js`),c,"utf-8");let d={OsClient:t.osClient,ModuleId:t.moduleId,[t.scriptField]:i},g=await r.post(K.UPDATE_MODULE,d,void 0,n?.apiBaseUrl,n);if(g.Code!==1)return M.error(`Microi: \u63A8\u9001\u6A21\u5757 ${t.scriptField} \u5931\u8D25 - ${g.Msg}`),!1;let m=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n),y=m.Data;if(m.Code!==1||!y||this.normalizeCode(String(y[t.scriptField]||""))!==this.normalizeCode(i))return M.error(`Microi: ${t.scriptField} \u63A5\u53E3\u8FD4\u56DE\u6210\u529F\uFF0C\u4F46\u8FDC\u7AEF\u56DE\u8BFB\u4E0D\u4E00\u81F4\uFF1B\u5DF2\u4FDD\u7559\u672C\u5730\u4FEE\u6539\u548C\u8FDC\u7AEF\u5907\u4EFD`),!1;let f=String(y.UpdateTime||g.Data?.UpdateTime||we()),h=this.loadMeta(t.serverDir);return h.menuScripts||(h.menuScripts={}),h.menuScripts[this.getMenuScriptMetaKey(t.moduleId,t.scriptField)]={moduleId:t.moduleId,moduleName:String(y.Label||y.Name||a.Label||a.Name||t.moduleId),scriptField:t.scriptField,codeHash:this.sourceHash(i),updateTime:f,filePath:v.relative(l.getWorkspaceRoot(),e)},h.menus||(h.menus={}),h.menus[t.moduleId]={moduleId:t.moduleId,moduleName:String(y.Label||y.Name||a.Label||a.Name||t.moduleId),updateTime:f,buttonHashes:h.menus[t.moduleId]?.buttonHashes||{}},this.saveMeta(h,t.serverDir),this.touchSyncedFile(e,f),this.log(`\u63A8\u9001\u5E76\u56DE\u8BFB\u6210\u529F: ${t.moduleId}.${t.scriptField}`),!0}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u6A21\u5757\u811A\u672C\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u6A21\u5757\u811A\u672C\u5F02\u5E38 - ${a}`),!1}}async pushMenuButtonFile(e,t,n){let r=j.getInstance(),i=_e(w.readFileSync(e,"utf-8"));this.log(`\u63A8\u9001\u6309\u94AEV8\u4EE3\u7801: ${t.moduleId}.${t.btnField}.${t.btnId}.${t.v8SubField}...`);try{let o=await r.get(K.GET_MODULE,{osClient:t.osClient,moduleId:t.moduleId},n?.apiBaseUrl,n);if(o.Code!==1)return M.error(`Microi: \u63A8\u9001\u5931\u8D25 - \u62C9\u53D6\u6A21\u5757\u5931\u8D25 ${o.Msg}`),!1;let a=o.Data,c=[],l=a[t.btnField];if(l)try{c=typeof l=="string"?JSON.parse(l):l,Array.isArray(c)||(c=[])}catch{return M.error("Microi: \u63A8\u9001\u5931\u8D25 - \u6309\u94AE JSON \u89E3\u6790\u5931\u8D25"),!1}let u=R.getInstance().getSyncRootDir();this.ensureSyncGitExcludes(u);let d=v.join(u,".backups","menu-button-json",this.shortBackupKey(t.serverDir),t.moduleId);ge(d);let g=v.join(d,`${t.btnField}-${Date.now()}.json`);w.writeFileSync(g,JSON.stringify(c,null,2),"utf-8");let m=c.find(h=>String(h.Id||"")===t.btnId);if(!m){let h=c.map(S=>Number(S.Sort||0)).filter(S=>!isNaN(S));m={Id:t.btnId,Name:t.btnName||t.btnId,Sort:h.length>0?Math.max(...h)+1:c.length+1,IsVisible:!0,ShowRow:t.btnField==="MoreBtns"},c.push(m)}m[t.v8SubField]=i;let y={OsClient:t.osClient,ModuleId:t.moduleId};y[t.btnField]=JSON.stringify(c);let f=await r.post(K.UPDATE_MODULE,y,void 0,n?.apiBaseUrl,n);if(f.Code===1){this.log(`\u63A8\u9001\u6210\u529F: ${t.moduleId}.${t.btnField}.${t.btnId}.${t.v8SubField}`);let h=f.Data?.UpdateTime||we(),S=this.loadMeta(t.serverDir);S.menuButtons||(S.menuButtons={});let C=this.getMenuButtonMetaKey(t.moduleId,t.btnField,t.btnId,t.v8SubField);return i.trim()?S.menuButtons[C]={moduleId:t.moduleId,moduleName:String(a.Name||a.Label||t.moduleId),btnField:t.btnField,btnId:t.btnId,btnName:String(m.Name||t.btnName||t.btnId),v8SubField:t.v8SubField,updateTime:h,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)}:delete S.menuButtons[C],S.menus||(S.menus={}),S.menus[t.moduleId]={moduleId:t.moduleId,moduleName:String(a.Name||a.Label||t.moduleId),updateTime:h,buttonHashes:S.menus[t.moduleId]?.buttonHashes||{}},this.saveMeta(S,t.serverDir),i.trim()?this.touchSyncedFile(e,h):w.existsSync(e)&&w.unlinkSync(e),!0}return M.error(`Microi: \u63A8\u9001\u6309\u94AE\u5931\u8D25 - ${f.Msg}`),!1}catch(o){let a=o instanceof Error?o.message:String(o);return this.log(`\u63A8\u9001\u5F02\u5E38: ${a}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${a}`),!1}}async pushWorkflowNodeFile(e,t,n){let r=j.getInstance(),i=w.readFileSync(e,"utf-8"),o=_e(i);this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8: ${t.flowDesignId}/${t.nodeId}/${t.eventType}...`);try{let a="",c="";try{let g=await r.post(K.GET_WORKFLOW_V8_EVENT_CODE,{OsClient:t.osClient,FlowDesignId:t.flowDesignId,NodeId:t.nodeId,EventType:t.eventType},void 0,n?.apiBaseUrl,n);g.Code===1&&g.Data&&(a=g.Data.V8Code||g.Data.Code||"",c=g.Data.Version||"")}catch{a="",c=""}let l=!o.trim(),p=l?{code:"",version:c,changeHistory:""}:bt({kind:"Workflow",key:`${t.flowDesignId}/${t.nodeId}`,eventType:t.eventType,currentCode:o,remoteCode:a,remoteVersion:c,changeSummary:`\u901A\u8FC7 VS Code \u63A8\u9001\u6D41\u7A0B\u8282\u70B9 V8 ${t.flowDesignId}/${t.nodeId}/${t.eventType}`}),u={OsClient:t.osClient,FlowDesignId:t.flowDesignId,NodeId:t.nodeId,EventType:t.eventType};l?u.V8Code="":(u.V8CodeBase64=Buffer.from(p.code,"utf8").toString("base64"),u.Version=p.version,u.ChangeHistory=p.changeHistory);let d=await r.post(K.UPDATE_WORKFLOW_V8_EVENT_CODE,u,void 0,n?.apiBaseUrl,n);if(d.Code===1){let g=d.Data?.UpdateTime||we(),m=this.loadMeta(t.serverDir);m.workflowNodeEvents||(m.workflowNodeEvents={});let y=`${t.flowDesignId}__${t.nodeId}__${t.eventType}`;return l?delete m.workflowNodeEvents[y]:m.workflowNodeEvents[y]={flowDesignId:t.flowDesignId,flowName:m.workflowNodeEvents[y]?.flowName||t.flowDesignId,nodeId:t.nodeId,nodeName:m.workflowNodeEvents[y]?.nodeName||t.nodeId,eventType:t.eventType,updateTime:g,filePath:v.relative(R.getInstance().getWorkspaceRoot(),e)},this.saveMeta(m,t.serverDir),l?w.existsSync(e)&&w.unlinkSync(e):(w.writeFileSync(e,p.code,"utf-8"),this.touchSyncedFile(e,g)),this.log(`\u63A8\u9001\u6210\u529F: ${t.flowDesignId}/${t.nodeId}/${t.eventType}`),!0}return this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5931\u8D25: ${d.Msg}`),M.error(`Microi: \u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5931\u8D25 - ${d.Msg}`),!1}catch(a){let c=a instanceof Error?a.message:String(a);return this.log(`\u63A8\u9001\u6D41\u7A0B\u8282\u70B9V8\u5F02\u5E38: ${c}`),M.error(`Microi: \u63A8\u9001\u5F02\u5E38 - ${c}`),!1}}async pullDbSchema(e){let t=R.getInstance(),n=j.getInstance();if(!e){let r=t.getProfiles();if(r.length===0){M.warn("Microi: \u6CA1\u6709\u5DF2\u8FDE\u63A5\u7684\u670D\u52A1\u5668");return}for(let i of r)try{await this.pullDbSchemaForProfile(i)}catch(o){let a=o instanceof Error?o.message:String(o);this.log(`\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5931\u8D25 [${i.label||i.apiBaseUrl}]: ${a}`)}return}await this.pullDbSchemaForProfile(e)}async pullDbSchemaForProfile(e){let t=R.getInstance(),n=j.getInstance(),r=e.apiBaseUrl,i=e.osClient;this.log(`\u5F00\u59CB\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784 [${e.label||r}]...`);let o=await n.get(K.GET_DB_SCHEMA,{osClient:i},r,e);if(o.Code!==1){let b=o.Code===1001||o.Code===1002?"\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55":"";throw new Error(`\u83B7\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5931\u8D25: ${o.Msg||"Code="+o.Code}${b}`)}let a=t.getSyncRootDir(),l=await Ce.getInstance().getSysConfig(r,i),p=l?.SysShortTitle||"",u=l?.SysTitle||"",d=p||u||l?.CompanyName||e.label||"";d&&(d!==e.label||p!==e.sysShortTitle||u!==e.sysTitle)&&await t.addProfile({...e,label:d,sysShortTitle:p,sysTitle:u});let g=t.buildServerDirName(d,r),y=t.getProfiles().find(b=>b.apiBaseUrl===e.apiBaseUrl&&b.osClient===e.osClient)||e,f=t.buildOsClientDirName(i,y.osClientType,y.osClientNetwork),h=v.join(a,g,f);ge(h);let S=v.join(h,tt);w.writeFileSync(S,JSON.stringify(o.Data,null,2),"utf-8");let C=v.join(h,He),T=this.formatDbSchemaMarkdown(o.Data,g,f);T&&w.writeFileSync(C,T,"utf-8");let k=o.Data.Tables?.length||0,E=d||e.label||r;this.log(`[${E}] \u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\u5B8C\u6210: ${k} \u5F20\u8868`),M.info(`Microi: [${E}] \u6210\u529F\u62C9\u53D6\u6570\u636E\u5E93\u7ED3\u6784\uFF08${k} \u5F20\u8868\uFF09`)}formatDbSchemaMarkdown(e,t,n){let r=(e.Tables||[]).filter(c=>c.Name);if(!r.length)return"";let i=r.reduce((c,l)=>{let p=l._Fields||l.Fields||[];return c+p.length},0),o=e.Menus?.length||0,a=[];a.push(`# \u6570\u636E\u5E93\u7ED3\u6784 \u2014 ${t}/${n}
|
|
42
42
|
`),a.push("> \u6B64\u6587\u4EF6\u7531 Microi\u543E\u7801 VS Code \u63D2\u4EF6\u81EA\u52A8\u751F\u6210\uFF0C\u4F9B AI \u7F16\u5199 V8.FormEngine / V8.Db \u4EE3\u7801\u65F6\u53C2\u8003\u3002"),a.push(`> \u5171 ${r.length} \u5F20\u8868\uFF0C${i} \u4E2A\u5B57\u6BB5\uFF0C${o} \u4E2A\u83DC\u5355\u3002
|
|
43
43
|
`);for(let c of r){let l=c.Description?` \u2014 ${c.Description}`:"";a.push(`## ${c.Name}${l}
|
|
44
44
|
`);let p=c._Fields||c.Fields||[];if(!p.length){a.push(`_\u6682\u65E0\u5B57\u6BB5\u4FE1\u606F._
|
|
@@ -1255,7 +1255,7 @@ return { Code:1, Data:{ FileName:'a.png', ContentType:'image/png', FileByteBase6
|
|
|
1255
1255
|
|
|
1256
1256
|
**\u5F02\u6B65\u4E0E\u540E\u53F0\u4EFB\u52A1\uFF1A** \u8BF7\u6C42\u5185\u5F02\u6B65\u65B9\u6CD5\u4F7F\u7528 \`await\`\uFF1B\`setTimeout\` / \`Task.Run\` \u4E0D\u80FD\u4FDD\u8BC1\u8BF7\u6C42\u8FD4\u56DE\u540E\u7EE7\u7EED\u5DE5\u4F5C\uFF0C\u56E0\u4E3A Engine\u3001\u79DF\u6237\u4E0A\u4E0B\u6587\u548C\u4E8B\u52A1\u4F1A\u88AB\u91CA\u653E\u3002\u9884\u8BA1\u8D85\u8FC7 2 \u5206\u949F\u3001500 \u6761\u30011000 \u4E2A\u6247\u51FA\u5B50\u64CD\u4F5C\u3001100 \u6B21\u5916\u90E8\u8C03\u7528\u6216\u5B89\u88C5/\u521D\u59CB\u5316/\u8FC1\u79FB/\u5907\u4EFD\u7C7B\u5DE5\u4F5C\uFF0C\u4F7F\u7528 \`V8.ApiEngine.RunBackground\` \u5E76\u914D\u7F6E\u7A33\u5B9A \`IdempotencyKey\`\u3002\u4E1A\u52A1\u8BB0\u5F55\u81F3\u5C11\u5199\u201C\u5904\u7406\u4E2D\u201D\u72B6\u6001\u548C \`BackgroundTaskId\`\uFF1B\u901A\u8FC7 \`V8.Method.UpdateBackgroundTask({Current,Total,Msg})\` \u4E0A\u62A5\u771F\u5B9E\u5355\u4F4D\uFF0C\u5E73\u53F0\u6839\u636E\u5B9E\u9645\u541E\u5410\u4F30\u7B97\u7ED3\u675F\u65F6\u95F4\u3002\u603B\u91CF\u672A\u77E5\u65F6\u4E0D\u8981\u4F2A\u9020\u767E\u5206\u6BD4\uFF1B\u8D85\u8FC7 10 \u5206\u949F\u7684\u5DE5\u4F5C\u5FC5\u987B\u6309 checkpoint \u5206\u7247\u3001\u6BCF\u7247\u72EC\u7ACB\u4E8B\u52A1\u3002
|
|
1257
1257
|
|
|
1258
|
-
**Jint\u9884\u7B97\u4E0E\u5D4C\u5957\uFF1A** \`LimitMemory\` \u662F\u5355\u5C42Jint\u6267\u884C\u671F\u95F4\u7684\u7D2F\u8BA1\u6258\u7BA1\u5206\u914D\uFF0C\u4E0D\u662F\u5B9E\u65F6\u5806\u6216\u9884\u7559\u5185\u5B58\u3002\`V8.ApiEngine.Run\` \u591A\u5C42\u8C03\u7528\u662F\u6B63\u5E38\u80FD\u529B\uFF1B\u63A5\u53E3\u5D4C\u5957\u4E0EJavaScript\u51FD\u6570\u9012\u5F52\u662F\u4E24\u79CD\u9650\u5236\u3002\u7528 \`V8.Limits\` \u67E5\u770B\u672C\u7247\u6709\u6548\u9884\u7B97\u3002\u63A5\u53E3\u5F15\u64CE\u4F7F\u7528\u6B63\u5411 \`v8Limit\`\uFF1A\
|
|
1258
|
+
**Jint\u9884\u7B97\u4E0E\u5D4C\u5957\uFF1A** \`LimitMemory\` \u662F\u5355\u5C42Jint\u6267\u884C\u671F\u95F4\u7684\u7D2F\u8BA1\u6258\u7BA1\u5206\u914D\uFF0C\u4E0D\u662F\u5B9E\u65F6\u5806\u6216\u9884\u7559\u5185\u5B58\u3002\`V8.ApiEngine.Run\` \u591A\u5C42\u8C03\u7528\u662F\u6B63\u5E38\u80FD\u529B\uFF1B\u63A5\u53E3\u5D4C\u5957\u4E0EJavaScript\u51FD\u6570\u9012\u5F52\u662F\u4E24\u79CD\u9650\u5236\u3002\u7528 \`V8.Limits\` \u67E5\u770B\u672C\u7247\u6709\u6548\u9884\u7B97\u3002\u63A5\u53E3\u5F15\u64CE\u4E0E\u8868\u5355\u540E\u7AEF V8 \u4E8B\u4EF6\u90FD\u4F7F\u7528\u6B63\u5411 \`v8Limit\`\uFF1A\u7F3A\u5931\u3001\`null\` \u6216 \`false\` \u4E0D\u8BBE\u7F6E Jint \u5355\u6B21\u8D85\u65F6\u3001\u8BED\u53E5\u3001\u9012\u5F52\u548C\u7D2F\u8BA1\u5206\u914D\u9884\u7B97\uFF1B\u8BBE\u4E3A \`true\` \u624D\u5E94\u7528\u914D\u7F6E\u503C\u3002\u65E7 \`v8Unlimited\` \u53EA\u5728\u65B0\u5B57\u6BB5\u4E0D\u5B58\u5728\u65F6\u53CD\u5411\u517C\u5BB9\u3002\u8FDB\u7A0B\u5E38\u9A7B\u5185\u5B58\u4FDD\u62A4\u3001\u8BF7\u6C42\u53D6\u6D88\u3001\u5E76\u53D1\u3001\u5D4C\u5957\u6DF1\u5EA6\u3001\u6743\u9650\u548C\u6570\u636E\u5E93\u5B89\u5168\u8FB9\u754C\u5728\u4E24\u79CD\u6A21\u5F0F\u4E0B\u59CB\u7EC8\u751F\u6548\u3002
|
|
1259
1259
|
|
|
1260
1260
|
---
|
|
1261
1261
|
|