neo-cmp-cli 1.9.0 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,7 +112,7 @@ neo push cmp
112
112
  | `neo create cmp` | 在当前项目中创建一个自定义组件 | `--name` 指定组件名称 |
113
113
  | `neo login` | 登录 NeoCRM 平台(OAuth2 授权模式) | - |
114
114
  | `neo logout` | 登出 NeoCRM 平台 | - |
115
- | `neo preview` | 本地预览自定义组件内容,默认支持热更新与接口代理 | `--name` 指定组件名称 |
115
+ | `neo preview` | 本地预览自定义组件内容,默认支持热更新与接口代理。(备注:当自定义组件使用 neo-ui-common 或者 neo-ui-component-web 时则不支持本地预览。) | `--name` 指定组件名称 |
116
116
  | `neo linkDebug` | 外链调试模式,在平台端页面设计器中调试自定义组件 | `--name` 指定组件名称 |
117
117
  | `neo push cmp` | 构建并发布到 NeoCRM 平台 | `--name` 指定组件名称 |
118
118
  | `neo pull cmp` | 拉取线上自定义组件(NeoCRM 平台)至当前项目 | `--name` 指定组件名称 |
package/dist/main2.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("akfun");require("lodash");const r=require("./module/neoInit.js"),i=require("./module/neoInitByCopy.js"),s=require("./module/inspect.js"),t=require("./utils/neoConfigInit.js"),o=require("./utils/neoParams.js"),u=require("./config/index.js"),l=require("./oss/publish2oss.js"),p=require("./utils/cmpUtils/pushCmp.js"),n=require("./utils/cmpUtils/previewCmp.js"),c=require("./utils/generateEntries.js"),d=require("./utils/cmpUtils/createCmpByTemplate.js"),m=require("./utils/projectUtils/createCmpProjectByTemplate.js"),b=require("./utils/cmpUtils/pullCmp.js"),a=require("./utils/cmpUtils/deleteCmp.js"),q=require("./utils/projectUtils/openProject.js"),_=require("./utils/configureNeoBuild.js"),y=require("./utils/common.js"),g=require("./utils/projectNameValidator.js"),j=require("./utils/cmpUtils/getCmpTypeByDir.js"),v=require("./neo/neoService.js"),T=require("./neo/neoLogin.js"),f=require("./utils/projectUtils/hasNeoProject.js");var C,x;exports.__require=function(){if(x)return C;x=1;const h=e,E=r.__require(),N=i.__require(),w=s.__require(),B=t.__require(),{consoleTag:D}=o.__require(),P=u.__require(),U=l.__require(),k=p.__require(),I=n.__require(),L=c.__require(),M=d.__require(),O=m.__require(),S=b.__require(),R=a.__require(),A=q.__require(),{configureNeoBuild:V}=_.__require(),{errorLog:z,successLog:F}=y.__require(),{validateProjectName:G}=g.__require(),H=j.__require(),J=v.__require(),K=T.__require(),Q=f.__require();function W(e,r){const{entryType:i,cmpType:s}=r;let t=[],o={};try{const{entries:r,cmpTypes:u,defaultExports:l}=L({configEntry:e.entry,disableAutoRegister:e.disableAutoRegister,componentsDir:P.componentsDir,entryType:i,cmpType:s});r&&Object.keys(r).length>0&&(e.entry=r,t=u,console.info("已自动生成 entry 入口配置:",r)),o=l}catch(e){z(e.message),process.exit(1)}return{cmpTypes:t,defaultExports:o}}function X(e){return Object.assign(P.build2lib,e)}return C={neoInit:E,neoInitByCopy:N,inspect:w,neoConfigInit:B,projectConfig:P,consoleTag:D,errorLog:z,successLog:F,validateProjectName:G,getCmpTypeByDir:H,NeoService:J,NeoLoginService:K,hasNeoProject:Q,createCmpProjectByTemplate:O,createCmpByTemplate:M,dev:()=>{P.dev||(z("未找到 dev 相关配置。"),process.exit(1)),h.dev(P,D)},previewCmp:e=>{e||(z("请输入要预览的组件名称。"),process.exit(1)),P.preview||(z("未找到 preview 相关配置。"),process.exit(1)),P.dev=Object.assign(P.dev,P.preview),delete P.preview,I(P,e)},linkDebug:()=>{P.linkDebug||(z("未找到 debug 相关配置。"),process.exit(1)),P.dev=Object.assign(P.dev,P.linkDebug),delete P.linkDebug,delete P.dev.ignoreNodeModules,P.webpack.ignoreNodeModules=!1;const{cmpTypes:e,defaultExports:r}=W(P.dev,{entryType:"linkDebug"});V(P.dev,{cmpTypes:e,defaultExports:r,verbose:!0,excludeModel:!1}),h.dev(P,D)},build:()=>h.build("build",P,D),build2lib:()=>{W(P.build2lib,{entryType:"widget"}),h.build("lib",P,D)},publish2oss:e=>{const r=P.publish2oss;P.build2lib=X(r);const{cmpTypes:i,defaultExports:s}=W(P.build2lib,{entryType:"widget",cmpType:e});V(P.build2lib,{cmpTypes:i,defaultExports:s,verbose:!0,excludeModel:!0}),h.build("lib",P,D,()=>{U(r.ossType,r.ossConfig,r.assetsRoot)})},pushCmp:e=>{const{neoConfig:r,pushCmp:i}=P,s=Object.assign({},i,r);P.build2lib=X(s);const{cmpTypes:t,defaultExports:o}=W(P.build2lib,{entryType:"widget",cmpType:e});V(P.build2lib,{cmpTypes:t,defaultExports:o,verbose:!1,excludeModel:!0}),h.build("lib",P,D,()=>{k(s,e)})},pullCmp:(e,r)=>{S(e,P.neoConfig,r)},deleteCmp:(e,r)=>{R(e,P.neoConfig,r)},build2esm:()=>h.build2esm(P,D),openEditor:A},C};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("akfun");require("lodash");const r=require("./module/neoInit.js"),i=require("./module/neoInitByCopy.js"),s=require("./module/inspect.js"),t=require("./utils/neoConfigInit.js"),o=require("./utils/neoParams.js"),u=require("./config/index.js"),l=require("./oss/publish2oss.js"),p=require("./neo/pushCmp.js"),n=require("./neo/pullCmp.js"),c=require("./neo/deleteCmp.js"),d=require("./utils/cmpUtils/previewCmp.js"),b=require("./utils/generateEntries.js"),m=require("./utils/cmpUtils/createCmpByTemplate.js"),a=require("./utils/projectUtils/createCmpProjectByTemplate.js"),q=require("./utils/projectUtils/openProject.js"),_=require("./utils/configureNeoBuild.js"),y=require("./utils/common.js"),g=require("./utils/projectNameValidator.js"),j=require("./utils/cmpUtils/getCmpTypeByDir.js"),v=require("./neo/neoService.js"),T=require("./neo/neoLogin.js"),f=require("./utils/projectUtils/hasNeoProject.js");var C,x;exports.__require=function(){if(x)return C;x=1;const h=e,E=r.__require(),N=i.__require(),w=s.__require(),B=t.__require(),{consoleTag:D}=o.__require(),P=u.__require(),k=l.__require(),I=p.__require(),L=n.__require(),M=c.__require(),O=d.__require(),U=b.__require(),S=m.__require(),R=a.__require(),A=q.__require(),{configureNeoBuild:V}=_.__require(),{errorLog:z,successLog:F}=y.__require(),{validateProjectName:G}=g.__require(),H=j.__require(),J=v.__require(),K=T.__require(),Q=f.__require();function W(e,r){const{entryType:i,cmpType:s}=r;let t=[],o={};try{const{entries:r,cmpTypes:u,defaultExports:l}=U({configEntry:e.entry,disableAutoRegister:e.disableAutoRegister,componentsDir:P.componentsDir,entryType:i,cmpType:s});r&&Object.keys(r).length>0&&(e.entry=r,t=u,console.info("已自动生成 entry 入口配置:",r)),o=l}catch(e){z(e.message),process.exit(1)}return{cmpTypes:t,defaultExports:o}}function X(e){return Object.assign(P.build2lib,e)}return C={neoInit:E,neoInitByCopy:N,inspect:w,neoConfigInit:B,projectConfig:P,consoleTag:D,errorLog:z,successLog:F,validateProjectName:G,getCmpTypeByDir:H,NeoService:J,NeoLoginService:K,hasNeoProject:Q,createCmpProjectByTemplate:R,createCmpByTemplate:S,dev:()=>{P.dev||(z("未找到 dev 相关配置。"),process.exit(1)),h.dev(P,D)},previewCmp:e=>{e||(z("请输入要预览的组件名称。"),process.exit(1)),P.preview||(z("未找到 preview 相关配置。"),process.exit(1)),P.dev=Object.assign(P.dev,P.preview),delete P.preview,O(P,e)},linkDebug:()=>{P.linkDebug||(z("未找到 debug 相关配置。"),process.exit(1)),P.dev=Object.assign(P.dev,P.linkDebug),delete P.linkDebug,delete P.dev.ignoreNodeModules,P.webpack.ignoreNodeModules=!1;const{cmpTypes:e,defaultExports:r}=W(P.dev,{entryType:"linkDebug"});V(P.dev,{cmpTypes:e,defaultExports:r,verbose:!0,excludeModel:!1}),h.dev(P,D)},build:()=>h.build("build",P,D),build2lib:()=>{W(P.build2lib,{entryType:"widget"}),h.build("lib",P,D)},publish2oss:e=>{const r=P.publish2oss;P.build2lib=X(r);const{cmpTypes:i,defaultExports:s}=W(P.build2lib,{entryType:"widget",cmpType:e});V(P.build2lib,{cmpTypes:i,defaultExports:s,verbose:!0,excludeModel:!0}),h.build("lib",P,D,()=>{k(r.ossType,r.ossConfig,r.assetsRoot)})},pushCmp:e=>{const{neoConfig:r,pushCmp:i}=P,s=Object.assign({},i,r);P.build2lib=X(s);const{cmpTypes:t,defaultExports:o}=W(P.build2lib,{entryType:"widget",cmpType:e});V(P.build2lib,{cmpTypes:t,defaultExports:o,verbose:!1,excludeModel:!0}),h.build("lib",P,D,()=>{I(s,e)})},pullCmp:(e,r)=>{L(e,P.neoConfig,r)},deleteCmp:(e,r)=>{M(e,P.neoConfig,r)},build2esm:()=>h.build2esm(P,D),openEditor:A},C};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("ora"),r=require("./neoService.js"),t=require("../utils/common.js");var o,s;exports.__require=function(){if(s)return o;s=1;const i=e,n=r.__require(),{errorLog:c,successLog:u}=t.__require();return o=async(e,r,t)=>{if(!r)return void c("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");const o=i("正在删除组件...").start();try{let s=t,i=[],a=null;t?i=t.cmpList||[]:(s=new n(r),o.info("正在获取自定义组件列表..."),i=await s.getCustomCmpList()),0===i.length&&(c("删除失败,当前租户暂无任何自定义组件。",o),process.exit(1)),a=s.getCmpInfoByCmpType(e),a||(c(`删除失败,当前租户不存在${e}自定义组件。`,o),process.exit(1)),o.info(`正在删除${e}自定义组件...`),await s.deleteCmp(e),u(`已成功删除${e}自定义组件!\n`,o)}catch(e){c(`删除自定义组件失败: ${e.message}`,o),process.exit(1)}},o};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("axios"),n=require("node:fs"),t=require("node:path"),s=require("ora"),o=require("node:http"),r=require("node:url"),i=require("open"),c=require("node:net");require("portfinder");const a=require("../utils/common.js"),l=require("../config/auth.config.js");var p,d;exports.__require=function(){if(d)return p;d=1;const h=e,u=n,g=t,y=s,k=o,_=r,m=i,w=c,{errorLog:x,successLog:f}=a.__require(),T=l.__require();return p=class{constructor(e={}){const{loginURL:n,tokenAPI:t}=e;if(!n||!t)throw new Error("auth.config.js 配置不完整,需要包含 loginURL、tokenAPI");this.loginURL=n,this.tokenAPI=t,this.response_type=T.response_type||"code",this.client_id=T.client_id,this.client_secret=T.client_secret,this.scope=T.scope||"all",this.oauthType=T.oauthType||"standard",this.access_type=T.access_type||"offline",this.grant_type=T.grant_type||"authorization_code",this.tokenDir=g.join(process.cwd(),".neo-cli"),this.tokenFile=g.join(this.tokenDir,"token.json")}ensureTokenDir(){u.existsSync(this.tokenDir)||u.mkdirSync(this.tokenDir,{recursive:!0})}saveToken(e){this.ensureTokenDir();const n={...e,savedAt:Date.now(),expiresAt:Date.now()+1e3*(e.expires_in||7200)};u.writeFileSync(this.tokenFile,JSON.stringify(n,null,2),"utf-8")}readToken(){if(!u.existsSync(this.tokenFile))return null;try{return JSON.parse(u.readFileSync(this.tokenFile,"utf-8"))}catch(e){return x(`读取 token 文件失败: ${e.message}`),null}}isTokenExpired(e){return!e||!e.expiresAt||Date.now()>=e.expiresAt-3e5}clearToken(){u.existsSync(this.tokenFile)&&u.unlinkSync(this.tokenFile)}getRedirectURI(e){return`http://localhost:${e}`}buildAuthUrl(e){const n=new URLSearchParams({response_type:this.response_type,client_id:this.client_id,redirect_uri:e,scope:this.scope,oauthType:this.oauthType,access_type:this.access_type});return`${this.loginURL}?${n.toString()}`}async openBrowser(e){try{await m(e)}catch(n){x(`无法自动打开浏览器: ${n.message}`),console.log(`\n请手动访问以下 URL 进行授权:\n${e}\n`)}}async isPortInUse(e){return new Promise(n=>{const t=w.createServer();t.once("error",e=>{"EADDRINUSE"===e.code?n(!0):n(!1)}),t.once("listening",()=>{t.once("close",()=>{n(!1)}),t.close()}),t.listen(e)})}async startCallbackServer(){let e=T.redirectUri,n=new URL(e),t=parseInt(n.port,10);await this.isPortInUse(t)&&(consoleError(`\n警告: 端口 ${t} 已被占用,请调整 redirectUri 配置项,使其指向一个未被占用的端口。`),process.exit(1));const s=new Promise((s,o)=>{const r=k.createServer((e,t)=>{const i=_.parse(e.url,!0);if(i.pathname===n.pathname||"/"===i.pathname){const e=i.query.code,n=i.query.error;if(n)return t.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),t.end(`\n <html>\n <head>\n <title>授权失败</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n }\n .error-title {\n color: red;\n }\n h1, p {\n text-align: center;\n margin-top: 30px;\n }\n </style>\n </head>\n <body>\n <div class="container">\n <h1 class="error-title">授权失败</h1>\n <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权失败" />\n <p>错误信息: ${n}</p>\n </div>\n </body>\n </html>\n `),r.close(),void o(new Error(`授权失败: ${n}`));if(e){const n=this.readToken()||{},o=n.tenant_id,i=n.instance_uri;return t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(`\n <html>\n <head>\n <title>授权成功</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n }\n .success-title {\n color: green;\n }\n h1, .success-content {\n text-align: center;\n margin-top: 30px;\n }\n .success-content .title {\n font-size: 16px;\n font-weight: bold;\n }\n .success-content .detail {\n font-size: 14px;\n color: #666;\n }\n </style>\n </head>\n <body>\n <div class="container">\n <h1 class="success-title">授权成功!</h1>\n <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权成功" />\n <div class="success-content">\n <div class="title">您已成功授权开发账户,请关闭此页面。</div>\n <div class="detail">租户 ID: ${o},所在租户的 API 域名: ${i}。</div>\n </div>\n </div>\n </body>\n </html>\n `),r.close(),void s(e)}t.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),t.end('\n <html>\n <head>\n <title>授权失败</title>\n <style>\n .container {\n margin: 0 auto;\n padding-top: 30px;\n text-align: center;\n }\n .error-title {\n color: red;\n }\n h1, p {\n text-align: center;\n margin-top: 30px;\n }\n </style>\n </head>\n <body>\n <div class="container">\n <h1 class="error-title">授权失败</h1>\n <img src="https://custom-widgets.bj.bcebos.com/neocrmlogin.png" alt="授权失败" />\n <p>未获取到授权码。</p>\n </div>\n </body>\n </html>\n '),r.close(),o(new Error("未获取到授权码"))}else t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Not Found")});r.on("error",e=>{"EADDRINUSE"===e.code?o(new Error(`端口 ${t} 已被占用,无法启动回调服务器`)):o(e)}),r.listen(t,()=>{console.log(`\n本地回调服务器已启动,监听端口: ${t}`),console.log(`回调地址: ${e}`)}),setTimeout(()=>{r.close(),o(new Error("授权超时,请重试"))},3e5)});return{redirectUri:e,codePromise:s}}async getTokenByCode(e,n){const t=y("正在获取 access token...").start();try{const s=new URLSearchParams;s.append("grant_type",this.grant_type),s.append("client_id",this.client_id),s.append("client_secret",this.client_secret),s.append("code",e),s.append("redirect_uri",n);const o=(await h.post(this.tokenAPI,s.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data;return o&&o.access_token||(x("获取 token 失败:响应中未包含 access_token",t),x(`响应数据: ${JSON.stringify(o)}`),process.exit(1)),f("成功获取 access token",t),o}catch(e){x("获取 token 失败",t),x(`\n获取 token 失败: ${e.message}`),e.response&&x(`响应数据: ${JSON.stringify(e.response.data)}`),process.exit(1)}}async refreshToken(e){const n=y("正在刷新授权信息(token)...").start();try{const t=new URLSearchParams;t.append("grant_type","refresh_token"),t.append("client_id",this.client_id),t.append("client_secret",this.client_secret),t.append("refresh_token",e);const s=(await h.post(this.tokenAPI,t.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data;return s&&s.access_token?(f("刷新授权信息成功(token)。",n),s):(x("刷新授权信息失败:响应中未包含 access_token",n),x(`响应数据: ${JSON.stringify(s)}`),null)}catch(e){return x("刷新授权信息失败",n),x(`\n刷新授权信息失败: ${e.message}`),e.response&&x(`响应数据: ${JSON.stringify(e.response.data)}`),null}}async login(){console.log("\n========== NeoCRM 登录授权 ==========\n");try{const{redirectUri:e,codePromise:n}=await this.startCallbackServer(),t=this.buildAuthUrl(e);console.log("授权 URL:",t),console.log("\n正在打开浏览器进行授权..."),await this.openBrowser(t);const s=await n;f("\n✓ 已获取授权码");const o=await this.getTokenByCode(s,e);return this.saveToken(o),console.log("\n========== 登录成功 ==========\n"),console.log(`已缓存授权信息到: ${this.tokenFile}`),console.log(`实例地址: ${o.instance_uri||"未返回"}`),console.log(`租户 ID: ${o.tenant_id||"未返回"}`),console.log(`授权信息有效期(access_token): ${o.expires_in||7200} 秒`),console.log(`自动刷新授权信息有效期(refresh_token): ${o.refresh_token_expires_in||2592e3} 秒`),o}catch(e){x(`\n登录失败: ${e.message}`),process.exit(1)}}async logout(){if(console.log("\n========== NeoCRM 登出 ==========\n"),u.existsSync(this.tokenFile))try{this.clearToken(),f("已清除授权信息,下次登录需要重新授权。"),console.log("\n登出成功!\n")}catch(e){x(`登出失败: ${e.message}`),process.exit(1)}else console.log("当前未登录,无需登出。")}async getValidToken(){const e=this.readToken();if(e||(x("未找到授权信息,请先执行 neo login 进行登录。"),process.exit(1)),this.isTokenExpired(e)){console.log("授权信息已过期,正在尝试刷新..."),e.refresh_token||(x("自动刷新授权信息失败,请重新登录(neo login)。"),process.exit(1));const n=await this.refreshToken(e.refresh_token);return n||(x("刷新授权信息失败,请重新登录 (neo login)"),process.exit(1)),this.saveToken(n),n}return e}async getAccessToken(){return await this.getValidToken()}}};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("axios"),t=require("node:fs"),n=require("node:path"),s=require("ora"),r=require("node:http"),o=require("node:url"),i=require("open"),c=require("node:net");require("portfinder");const a=require("../utils/common.js"),l=require("../config/auth.config.js");var h,p;exports.__require=function(){if(p)return h;p=1;const u=e,d=t,g=n,k=s,y=r,_=o,m=i,T=c,{errorLog:f,successLog:w}=a.__require(),S=l.__require();return h=class{constructor(e={}){const{loginURL:t,tokenAPI:n}=e;if(!t||!n)throw new Error("auth.config.js 配置不完整,需要包含 loginURL、tokenAPI");this.loginURL=t,this.tokenAPI=n,this.response_type=S.response_type||"code",this.client_id=S.client_id,this.client_secret=S.client_secret,this.scope=S.scope||"all",this.oauthType=S.oauthType||"standard",this.access_type=S.access_type||"offline",this.grant_type=S.grant_type||"authorization_code",this.tokenDir=g.join(process.cwd(),".neo-cli"),this.tokenFile=g.join(this.tokenDir,"token.json"),this.pageDir=g.join(__dirname,"page"),this.authErrorTemplate=g.join(this.pageDir,"auth-error.html"),this.authSuccessTemplate=g.join(this.pageDir,"auth-success.html"),this.tokenErrorTemplate=g.join(this.pageDir,"token-error.html"),this.authFailedTemplate=g.join(this.pageDir,"auth-failed.html")}ensureTokenDir(){d.existsSync(this.tokenDir)||d.mkdirSync(this.tokenDir,{recursive:!0})}saveToken(e){this.ensureTokenDir();const t={...e,savedAt:Date.now(),expiresAt:Date.now()+1e3*(e.expires_in||7200)};d.writeFileSync(this.tokenFile,JSON.stringify(t,null,2),"utf-8")}readToken(){if(!d.existsSync(this.tokenFile))return null;try{return JSON.parse(d.readFileSync(this.tokenFile,"utf-8"))}catch(e){return f(`读取 token 文件失败: ${e.message}`),null}}isTokenExpired(e){return!e||!e.expiresAt||Date.now()>=e.expiresAt-3e5}clearToken(){d.existsSync(this.tokenFile)&&d.unlinkSync(this.tokenFile)}getRedirectURI(e){return`http://localhost:${e}`}buildAuthUrl(e){const t=new URLSearchParams({response_type:this.response_type,client_id:this.client_id,redirect_uri:e,scope:this.scope,oauthType:this.oauthType,access_type:this.access_type});return`${this.loginURL}?${t.toString()}`}async openBrowser(e){try{await m(e)}catch(t){f(`无法自动打开浏览器: ${t.message}`),console.log(`\n请手动访问以下 URL 进行授权:\n${e}\n`)}}getHtmlTemplate(e,t={}){try{let n=d.readFileSync(e,"utf-8");return Object.keys(t).forEach(e=>{const s=`{{${e}}}`;n=n.replace(new RegExp(s,"g"),t[e])}),n}catch(e){return f(`读取 HTML 模板失败: ${e.message}`),"<html><body><h1>页面加载失败</h1></body></html>"}}async isPortInUse(e){return new Promise(t=>{const n=T.createServer();n.once("error",e=>{"EADDRINUSE"===e.code?t(!0):t(!1)}),n.once("listening",()=>{n.once("close",()=>{t(!1)}),n.close()}),n.listen(e)})}async startCallbackServer(){let e=S.redirectUri,t=new URL(e),n=parseInt(t.port,10);await this.isPortInUse(n)&&(f(`\n警告: 端口 ${n} 已被占用,请调整 redirectUri 配置项,使其指向一个未被占用的端口。`),process.exit(1));const s=new Promise((s,r)=>{const o=y.createServer(async(n,i)=>{const c=_.parse(n.url,!0);if(c.pathname===t.pathname||"/"===c.pathname){const t=c.query.code,n=c.query.error;if(n){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"});const e=this.getHtmlTemplate(this.authErrorTemplate,{ERROR:n});return i.end(e),o.close(),void r(new Error(`授权失败: ${n}`))}if(t)try{const n=await this.getTokenByCode(t,e);this.saveToken(n);const r=n.tenant_id||"未返回",c=n.instance_uri||"未返回";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"});const a=this.getHtmlTemplate(this.authSuccessTemplate,{TENANT_ID:r,INSTANCE_URI:c});return i.end(a),o.close(),void s({code:t,tokenData:n})}catch(e){i.writeHead(500,{"Content-Type":"text/html; charset=utf-8"});const t=this.getHtmlTemplate(this.tokenErrorTemplate,{ERROR:e});return i.end(t),o.close(),void r(e)}i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"});const a=this.getHtmlTemplate(this.authFailedTemplate);i.end(a),o.close(),r(new Error("未获取到授权码"))}else i.writeHead(404,{"Content-Type":"text/plain"}),i.end("Not Found")});o.on("error",e=>{"EADDRINUSE"===e.code?r(new Error(`端口 ${n} 已被占用,无法启动回调服务器`)):r(e)}),o.listen(n,()=>{console.log(`\n本地回调服务器已启动,监听端口: ${n}`),console.log(`回调地址: ${e}`)}),setTimeout(()=>{o.close(),r(new Error("授权超时,请重试"))},3e5)});return{redirectUri:e,getCodeAndTokenPromise:s}}async getTokenByCode(e,t){const n=k("正在获取 access token...").start();try{const s=new URLSearchParams;s.append("grant_type",this.grant_type),s.append("client_id",this.client_id),s.append("client_secret",this.client_secret),s.append("code",e),s.append("redirect_uri",t);const r=(await u.post(this.tokenAPI,s.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data;return r&&r.access_token||(f("获取 token 失败:响应中未包含 access_token",n),f(`响应数据: ${JSON.stringify(r)}`),process.exit(1)),w("成功获取 access token",n),r}catch(e){f("获取 token 失败",n),f(`\n获取 token 失败: ${e.message}`),e.response&&f(`响应数据: ${JSON.stringify(e.response.data)}`),process.exit(1)}}async refreshToken(e){const t=k("正在刷新授权信息(token)...").start();try{const n=new URLSearchParams;n.append("grant_type","refresh_token"),n.append("client_id",this.client_id),n.append("client_secret",this.client_secret),n.append("refresh_token",e);const s=(await u.post(this.tokenAPI,n.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data;return s&&s.access_token?(w("刷新授权信息成功(token)。",t),s):(f("刷新授权信息失败:响应中未包含 access_token",t),f(`响应数据: ${JSON.stringify(s)}`),null)}catch(e){return f("刷新授权信息失败",t),f(`\n刷新授权信息失败: ${e.message}`),e.response&&f(`响应数据: ${JSON.stringify(e.response.data)}`),null}}async login(){console.log("\n========== NeoCRM 登录授权 ==========\n");try{const{redirectUri:e,getCodeAndTokenPromise:t}=await this.startCallbackServer(),n=this.buildAuthUrl(e);console.log("授权 URL:",n),console.log("\n正在打开浏览器进行授权..."),await this.openBrowser(n);const{code:s,tokenData:r}=await t();return w("\n✓ 已获取授权码"),console.log("\n========== 登录成功 ==========\n"),console.log(`已缓存授权信息到: ${this.tokenFile}`),console.log(`实例地址: ${r.instance_uri||"未返回"}`),console.log(`租户 ID: ${r.tenant_id||"未返回"}`),console.log(`授权信息有效期(access_token): ${r.expires_in||7200} 秒`),console.log(`自动刷新授权信息有效期(refresh_token): ${r.refresh_token_expires_in||2592e3} 秒`),r}catch(e){f(`\n登录失败: ${e.message}`),process.exit(1)}}async logout(){if(console.log("\n========== NeoCRM 登出 ==========\n"),d.existsSync(this.tokenFile))try{this.clearToken(),w("已清除授权信息,下次登录需要重新授权。"),console.log("\n登出成功!\n")}catch(e){f(`登出失败: ${e.message}`),process.exit(1)}else console.log("当前未登录,无需登出。")}async getValidToken(){const e=this.readToken();if(e||(f("未找到授权信息,请先执行 neo login 进行登录。"),process.exit(1)),this.isTokenExpired(e)){console.log("授权信息已过期,正在尝试刷新..."),e.refresh_token||(f("自动刷新授权信息失败,请重新登录(neo login)。"),process.exit(1));const t=await this.refreshToken(e.refresh_token);return t||(f("刷新授权信息失败,请重新登录 (neo login)"),process.exit(1)),this.saveToken(t),t}return e}async getAccessToken(){return await this.getValidToken()}}};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("lodash");const e=require("akfun"),r=require("ora"),t=require("./neoService.js"),o=require("../utils/common.js"),i=require("../utils/pathUtils.js"),s=require("../utils/cmpUtils/getCmpTypeByDir.js"),n=require("../utils/cmpUtils/createCmpByZip.js");var c,u;exports.__require=function(){if(u)return c;u=1;const{getConfigObj:a}=e,p=r,m=t.__require(),{getFramework:f,errorLog:g,successLog:l}=o.__require(),{catchCurPackageJson:q}=i.__require(),C=s.__require(),_=n.__require(),y=f(a(q()).framework);return c=async(e,r,t)=>{if(!r)return void g("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");C().indexOf(e)>-1&&(g(`当前项目目录中已存在${e}自定义组件。(./src/components 目录下)`),process.exit(1));const o=p("正在拉取组件...").start();try{let i=t,s=[],n={},c=null;t?(s=t.cmpList||[],n=t.cmpInfoMap||{}):(i=new m(r),o.info("正在获取自定义组件列表..."),s=await i.getCustomCmpList(),n=i.cmpInfoMap||{}),0===s.length&&(g("拉取失败,当前租户暂无任何自定义组件。",o),process.exit(1)),c=i.getCmpInfoByCmpType(e),c||(g(`拉取失败,当前租户不存在${e}自定义组件。`,o),process.exit(1)),c.framework&&c.framework!==y&&(g(`拉取失败,${e}自定义组件与当前项目技术栈不一致。`,o),process.exit(1));const u=i.getCodeLibByCmpType(e),a=await i.ensureValidToken();await _(u,{token:a,cmpName:e,componentBaseDir:"./src/components"})||(g(`拉取失败,${e}自定义组件源码解析失败,请检查源码文件是否正确。`,o),process.exit(1)),l(`已成功拉取${e}自定义组件!\n`,o)}catch(e){throw g(`拉取自定义组件失败: ${e.message}`,o),e}},c};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("node:fs"),t=require("node:path"),s=require("lodash"),o=require("akfun"),r=require("ora"),i=require("./neoService.js"),a=require("../utils/common.js"),n=require("../utils/pathUtils.js"),c=require("../utils/projectUtils/createCmpProjectZip.js");var l,p;exports.__require=function(){if(p)return l;p=1;const g=e,u=t,m=s,{getConfigObj:d}=o,w=r,h=i.__require(),{getFramework:y,errorLog:b,successLog:v}=a.__require(),{catchCurPackageJson:C}=n.__require(),f=c.__require(),T=d(C()),$=(e=[])=>e.map(e=>({label:e.label,description:e.description,propSchema:JSON.stringify(e)})),q=(e=[],t)=>e&&0!==e.length?e.map(e=>({...e,componentType:t,eventCategory:e.eventCategory||2,pageType:e.pageType||1,targetDevice:e.targetDevice||1,eventParams:e.eventParams||[]})):[];return l=async(e,t)=>{const s=w("正在发布组件...").start();try{let o,r=new h(e);await r.ensureValidToken(),s.start("[1/4] 打包源码文件(含单个自定义组件源码)...");try{o=f(t,process.cwd(),e.assetsRoot),o?v(`[1/4] 源码文件打包完成: ${u.basename(o)}。`,s):b("[1/4] 源码文件打包失败,未返回 zip 文件路径。",s)}catch(e){b("[1/4] 源码文件打包失败。",s)}s.start("[2/4] 获取自定义组件构建产物...");const i=await r.getCmpAssets(t);let a;s.start("[3/4] 构建组件数据...");try{a=await(async(e,t)=>{if(!t||!t.cmpType)return b("自定义组件信息或组件名称不能为空"),null;const{cmpType:s}=t;if(!e||!g.existsSync(e))return b(`未找到自定义组件目录: ${e}`),null;const o=m.camelCase(s),r=u.join(e,`${o}Model.js`),i=globalThis.window;globalThis.window||(globalThis.window={console:console,neoRequire:()=>{},postMessage:()=>{}});try{g.existsSync(r)?require(r):(b(`未找到自定义组件模型文件,请检查以下路径是否存在:${r}`),process.exit(1)),globalThis.window&&globalThis.window.NEOEditorCustomModels||(b(`模型文件未导出有效模型方法(CatchCustomCmpModelClass),模型文件地址: ${r} `),process.exit(1));const e=globalThis.window.NEOEditorCustomModels[s];e||(b(`未找到自定义组件模型类(${s}),模型文件地址: ${r} `),process.exit(1));const o=new e;o||(b(`未找到自定义组件模型信息(${s}),模型文件地址: ${r} `),process.exit(1));const i={...t,version:T.version||"1.0.0",framework:T.framework?y(T.framework):0,label:o.label||s,description:o.description||"",componentCategory:(o.tags||["自定义组件"]).join(","),targetPage:o.targetPage||["customPage"],targetObject:o.targetObject||["all"],targetApplication:o.targetApplication||["all"],targetDevice:o.targetDevice||"all",iconUrl:o.iconUrl||o.iconUrl,defaultProps:JSON.stringify(o.defaultComProps||{}),previewProps:JSON.stringify(o.previewComProps||{}),props:$(o.propsSchema||[]),events:q(o.events||[],s),functions:o.functions||o.actions||[],exposedToDesigner:void 0===o.exposedToDesigner||o.exposedToDesigner,namespace:o.namespace||"neo-cmp-cli",enableDuplicate:void 0===o.enableDuplicate||o.enableDuplicate};return console.log(`自定义组件模型信息(${s}):`,m.omit(i,["assetFile","modelAssetFile","cssAssetFile","codeLibFile"])),i}catch(e){return b(`自定义组件模型文件解析失败 (${r||"未知路径"}): ${e.message}`),b(e.stack),null}finally{void 0===i?delete globalThis.window:globalThis.window=i}})(e.assetsRoot,i),a?v("[3/4] 组件数据构建完成。",s):b(`[3/4] 未获取到自定义组件模型信息(${t})。`,s)}catch(e){b(`[3/4] 组件数据构建失败: ${e.message}`,s)}s.start("[4/4] 保存组件信息到 NeoCRM 平台...");try{await r.updateCustomComponent(a),v("[4/4] 组件信息保存成功",s)}catch(e){b("[4/4] 组件信息保存失败",s)}const{tenant_id:n,instance_uri:c}=r.tokenCache||{};console.log(`\n✅ 自定义组件发布成功!\n(当前租户 ID: ${n||"未返回"},所在租户的 API 域名: ${c||"未返回"}。)`)}catch(e){try{s&&s.isSpinning&&b(`❌ 自定义组件发布失败: ${e.message}`,s)}catch{b(`\n❌ 自定义组件发布失败: ${e.message}`)}throw e}},l};
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.9.0";const o={version:e};exports.default=o,exports.version=e;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.9.2";const o={version:e};exports.default=o,exports.version=e;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo-cmp-cli",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "Neo 自定义组件开发工具,支持react 和 vue2.0技术栈。",
5
5
  "keywords": [
6
6
  "neo-cli",
@@ -48,7 +48,7 @@
48
48
  "@commitlint/config-conventional": "^9.1.1",
49
49
  "@types/react": "^16.9.11",
50
50
  "@types/react-dom": "^16.9.15",
51
- "neo-cmp-cli": "^1.9.0",
51
+ "neo-cmp-cli": "^1.9.1",
52
52
  "husky": "^4.2.5",
53
53
  "lint-staged": "^10.2.9",
54
54
  "prettier": "^2.0.5"
@@ -48,7 +48,7 @@
48
48
  "@commitlint/config-conventional": "^9.1.1",
49
49
  "@types/react": "^16.9.11",
50
50
  "@types/react-dom": "^16.9.15",
51
- "neo-cmp-cli": "^1.9.0",
51
+ "neo-cmp-cli": "^1.9.1",
52
52
  "husky": "^4.2.5",
53
53
  "lint-staged": "^10.2.9",
54
54
  "prettier": "^2.0.5",
@@ -46,7 +46,7 @@
46
46
  "@commitlint/config-conventional": "^9.1.1",
47
47
  "@types/react": "^16.9.11",
48
48
  "@types/react-dom": "^16.9.15",
49
- "neo-cmp-cli": "^1.9.0",
49
+ "neo-cmp-cli": "^1.9.1",
50
50
  "husky": "^4.2.5",
51
51
  "lint-staged": "^10.2.9",
52
52
  "prettier": "^2.0.5"
@@ -13,6 +13,7 @@
13
13
  "scripts": {
14
14
  "preview": "neo preview",
15
15
  "linkDebug": "neo linkDebug",
16
+ "neoLogin": "neo login",
16
17
  "pushCmp": "neo push cmp",
17
18
  "pullCmp": "neo pull cmp",
18
19
  "deleteCmp": "neo delete cmp",
@@ -54,7 +55,7 @@
54
55
  "@types/react": "^16.9.11",
55
56
  "@types/react-dom": "^16.9.15",
56
57
  "@types/axios": "^0.14.0",
57
- "neo-cmp-cli": "^1.9.0",
58
+ "neo-cmp-cli": "^1.9.1",
58
59
  "husky": "^4.2.5",
59
60
  "lint-staged": "^10.2.9",
60
61
  "prettier": "^2.0.5"
@@ -29,7 +29,7 @@ import { xObject } from 'neo-open-api'; // Neo Open API
29
29
  import isEqual from 'lodash/isEqual';
30
30
  // 引入 neo-ui-common / aop
31
31
  // @ts-ignore
32
- import { aop } from 'neo-ui-common';
32
+ import { aop } from 'neo-ui-common'; // 后续考虑 使用 props.dispatchEvent 方法替代
33
33
  import './style.scss';
34
34
 
35
35
  const { Option } = Select;
@@ -238,6 +238,11 @@ export default class EntityForm extends React.PureComponent<
238
238
  console.log('触发了表单提交事件:', this.props);
239
239
  }
240
240
 
241
+ @aop
242
+ onBeforeSubmit(formValues: any) {
243
+ console.log('触发了表单提交前事件:', formValues);
244
+ }
245
+
241
246
  /**
242
247
  * 处理表单提交
243
248
  * 执行新增操作
@@ -247,6 +252,9 @@ export default class EntityForm extends React.PureComponent<
247
252
  const { xObjectApiKey } = this.props.xObjectDataApi || {};
248
253
  const { fieldList } = this.state;
249
254
 
255
+ // 触发表单提交事件
256
+ this.onBeforeSubmit(values);
257
+
250
258
  if (!xObjectApiKey) {
251
259
  message.error('请先选择要操作的对象');
252
260
  return;
@@ -62,6 +62,11 @@ export class EntityFormModel {
62
62
  label: '提交表单后', // 事件
63
63
  helpText: '表单提交后触发该事件' // 信息icon hover 时的提示文本
64
64
  },
65
+ {
66
+ apiKey: 'onBeforeSubmit',
67
+ label: '提交表单前',
68
+ helpText: '表单提交前触发该事件'
69
+ },
65
70
  ];
66
71
 
67
72
  /**
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@commitlint/cli": "^8.3.5",
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
- "neo-cmp-cli": "^1.9.0",
48
+ "neo-cmp-cli": "^1.9.1",
49
49
  "husky": "^4.2.5",
50
50
  "lint-staged": "^10.2.9",
51
51
  "prettier": "^2.0.5"
@@ -47,7 +47,7 @@
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
48
  "@types/react": "^16.9.11",
49
49
  "@types/react-dom": "^16.9.15",
50
- "neo-cmp-cli": "^1.9.0",
50
+ "neo-cmp-cli": "^1.9.1",
51
51
  "husky": "^4.2.5",
52
52
  "lint-staged": "^10.2.9",
53
53
  "prettier": "^2.0.5"
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@commitlint/cli": "^8.3.5",
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
- "neo-cmp-cli": "^1.9.0",
48
+ "neo-cmp-cli": "^1.9.1",
49
49
  "husky": "^4.2.5",
50
50
  "lint-staged": "^10.2.9",
51
51
  "prettier": "^2.0.5",
@@ -1,7 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
 
3
3
  // 所有需要废弃的版本
4
- const versionsToDeprecate = ["1.8.20", "1.8.21", "1.8.22", "1.8.23", "1.8.24", "1.8.25"];
4
+ const versionsToDeprecate = ["1.8.25", "1.9.0"];
5
5
 
6
6
  const packageName = 'neo-cmp-cli';
7
7
  const deprecateMessage = '此版本为开发中版本(存在 bug),请升级到最新版本。';
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("ora"),r=require("../../neo/neoService.js"),t=require("../common.js");var o,s;exports.__require=function(){if(s)return o;s=1;const i=e,n=r.__require(),{errorLog:c,successLog:u}=t.__require();return o=async(e,r,t)=>{if(!r)return void c("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");const o=i("正在删除组件...").start();try{let s=t,i=[],a=null;t?i=t.cmpList||[]:(s=new n(r),o.info("正在获取自定义组件列表..."),i=await s.getCustomCmpList()),0===i.length&&(c("删除失败,当前租户暂无任何自定义组件。",o),process.exit(1)),a=s.getCmpInfoByCmpType(e),a||(c(`删除失败,当前租户不存在${e}自定义组件。`,o),process.exit(1)),o.info(`正在删除${e}自定义组件...`),await s.deleteCmp(e),u(`已成功删除${e}自定义组件!\n`,o)}catch(e){c(`删除自定义组件失败: ${e.message}`,o),process.exit(1)}},o};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("lodash");const e=require("akfun"),r=require("../pathUtils.js"),o=require("ora"),t=require("../../neo/neoService.js"),i=require("../common.js"),s=require("./getCmpTypeByDir.js"),n=require("./createCmpByZip.js");var c,a;exports.__require=function(){if(a)return c;a=1;const{getConfigObj:p}=e,{catchCurPackageJson:u}=r.__require(),m=o,f=t.__require(),{getFramework:g,errorLog:q,successLog:C}=i.__require(),_=s.__require(),y=n.__require(),l=g(p(u()).framework);return c=async(e,r,o)=>{if(!r)return void q("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");_().indexOf(e)>-1&&(q(`当前项目目录中已存在${e}自定义组件。(./src/components 目录下)`),process.exit(1));const t=m("正在拉取组件...").start();try{let i=o,s=[],n={},c=null;o?(s=o.cmpList||[],n=o.cmpInfoMap||{}):(i=new f(r),t.info("正在获取自定义组件列表..."),s=await i.getCustomCmpList(),n=i.cmpInfoMap||{}),0===s.length&&(q("拉取失败,当前租户暂无任何自定义组件。",t),process.exit(1)),c=i.getCmpInfoByCmpType(e),c||(q(`拉取失败,当前租户不存在${e}自定义组件。`,t),process.exit(1)),c.framework&&c.framework!==l&&(q(`拉取失败,${e}自定义组件与当前项目技术栈不一致。`,t),process.exit(1));const a=i.getCodeLibByCmpType(e),p=await i.ensureValidToken();await y(a,{token:p,cmpName:e,componentBaseDir:"./src/components"})||(q(`拉取失败,${e}自定义组件源码解析失败,请检查源码文件是否正确。`,t),process.exit(1)),C(`已成功拉取${e}自定义组件!\n`,t)}catch(e){throw q(`拉取自定义组件失败: ${e.message}`,t),e}},c};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("node:fs"),t=require("node:path"),o=require("lodash"),s=require("akfun"),r=require("../pathUtils.js"),a=require("ora"),i=require("../../neo/neoService.js"),n=require("../common.js"),c=require("../projectUtils/createCmpProjectZip.js");var l,p;exports.__require=function(){if(p)return l;p=1;const g=e,u=t,m=o,{getConfigObj:d}=s,{catchCurPackageJson:w}=r.__require(),h=a,y=i.__require(),{getFramework:b,errorLog:v,successLog:C}=n.__require(),f=c.__require(),T=d(w()),$=(e=[])=>e.map(e=>({label:e.label,description:e.description,propSchema:JSON.stringify(e)})),q=(e=[],t)=>e&&0!==e.length?e.map(e=>({...e,componentType:t,eventCategory:e.eventCategory||2,pageType:e.pageType||1,targetDevice:e.targetDevice||1,eventParams:e.eventParams||[]})):[];return l=async(e,t)=>{const o=h("正在发布组件...").start();try{let s,r=new y(e);await r.ensureValidToken(),o.start("[1/4] 打包源码文件(含单个自定义组件源码)...");try{s=f(t,process.cwd(),e.assetsRoot),s?C(`[1/4] 源码文件打包完成: ${u.basename(s)}。`,o):v("[1/4] 源码文件打包失败,未返回 zip 文件路径。",o)}catch(e){v("[1/4] 源码文件打包失败。",o)}o.start("[2/4] 获取自定义组件构建产物...");const a=await r.getCmpAssets(t);let i;o.start("[3/4] 构建组件数据...");try{i=await(async(e,t)=>{if(!t||!t.cmpType)return v("自定义组件信息或组件名称不能为空"),null;const{cmpType:o}=t;if(!e||!g.existsSync(e))return v(`未找到自定义组件目录: ${e}`),null;const s=m.camelCase(o),r=u.join(e,`${s}Model.js`),a=globalThis.window;globalThis.window||(globalThis.window={console:console,neoRequire:()=>{},postMessage:()=>{}});try{g.existsSync(r)?require(r):(v(`未找到自定义组件模型文件,请检查以下路径是否存在:${r}`),process.exit(1)),globalThis.window&&globalThis.window.NEOEditorCustomModels||(v(`模型文件未导出有效模型方法(CatchCustomCmpModelClass),模型文件地址: ${r} `),process.exit(1));const e=globalThis.window.NEOEditorCustomModels[o];e||(v(`未找到自定义组件模型类(${o}),模型文件地址: ${r} `),process.exit(1));const s=new e;s||(v(`未找到自定义组件模型信息(${o}),模型文件地址: ${r} `),process.exit(1));const a={...t,version:T.version||"1.0.0",framework:T.framework?b(T.framework):0,label:s.label||o,description:s.description||"",componentCategory:(s.tags||["自定义组件"]).join(","),targetPage:s.targetPage||["customPage"],targetObject:s.targetObject||["all"],targetApplication:s.targetApplication||["all"],targetDevice:s.targetDevice||"all",iconUrl:s.iconUrl||s.iconUrl,defaultProps:JSON.stringify(s.defaultComProps||{}),previewProps:JSON.stringify(s.previewComProps||{}),props:$(s.propsSchema||[]),events:q(s.events||[],o),functions:s.functions||s.actions||[],exposedToDesigner:void 0===s.exposedToDesigner||s.exposedToDesigner,namespace:s.namespace||"neo-cmp-cli",enableDuplicate:void 0===s.enableDuplicate||s.enableDuplicate};return console.log(`自定义组件模型信息(${o}):`,m.omit(a,["assetFile","modelAssetFile","cssAssetFile","codeLibFile"])),a}catch(e){return v(`自定义组件模型文件解析失败 (${r||"未知路径"}): ${e.message}`),v(e.stack),null}finally{void 0===a?delete globalThis.window:globalThis.window=a}})(e.assetsRoot,a),i?C("[3/4] 组件数据构建完成。",o):v(`[3/4] 未获取到自定义组件模型信息(${t})。`,o)}catch(e){v(`[3/4] 组件数据构建失败: ${e.message}`,o)}o.start("[4/4] 保存组件信息到 NeoCRM 平台...");try{await r.updateCustomComponent(i),C("[4/4] 组件信息保存成功",o)}catch(e){v("[4/4] 组件信息保存失败",o)}const{tenant_id:n,instance_uri:c}=r.tokenCache||{};console.log(`\n✅ 自定义组件发布成功!\n(当前租户 ID: ${n},所在租户的 API 域名: ${c}。)`)}catch(e){try{o&&o.isSpinning&&v(`❌ 自定义组件发布失败: ${e.message}`,o)}catch{v(`\n❌ 自定义组件发布失败: ${e.message}`)}throw e}},l};